Pretty.c - C के ऊपर चलने वाली scripting
(github.com/aartaka)- Pretty C, C-compatible नई scripting language है, जो C programs में dynamic typing, generic iteration, resource tracking जैसी convenience features जोड़ती है
- इसे इस्तेमाल करने का तरीका
pretty.hको include करने वाली header-only library के रूप में है, और इसे existing C files व C libraries के साथ इस्तेमाल किया जा सकता है - इसमें
string,any,nilजैसे aliases,var/lettype inference,print/printlngeneric output,equalgeneric comparison, और पढ़ने में आसान ternary-expression macros शामिल हैं - iteration और memory work घटाने के लिए यह
foreach,forthese,fortimes,forrange,new,vector,delete,with,lambda,try/catchजैसी macro-based syntax देता है - कुछ features के लिए GCC, Clang, C23+, C11+ जैसी शर्तें हैं, और
withसे bound variablesvoid *होते हैं, इसलिए इस्तेमाल से पहले type conversion की जरूरत पड़ सकती है
Pretty C का लक्ष्य और इस्तेमाल का तरीका
- Pretty C, C-compatible scripting language है और C programs में dynamic typing, generic iteration, resource tracking तथा कई syntax convenience features जोड़ती है
- existing C और C libraries के साथ backward compatibility बनाए रखती है
- Lua, Python, JavaScript, Lisp से प्रेरित है
- installation के लिए repository clone की जा सकती है या सिर्फ
pretty.hfile copy करके इस्तेमाल किया जा सकता है- किसी भी C file में
#include "pretty.h"से include किया जा सकता है - include path में Pretty C path specify करके भी इस्तेमाल किया जा सकता है
- किसी भी C file में
Basic included headers और simple macros
- Pretty C standard headers include करता है ताकि अक्सर इस्तेमाल होने वाले types और operator replacements तुरंत इस्तेमाल किए जा सकें
- अक्सर define किए जाने वाले simple macros भी देता है
max,min: दो numbers का maximum और minimumlen: array lengthdefault: fallback value देता हैlimit: value range limit करता हैbetween: जांचता है कि number range के अंदर है या नहींdivisible: जांचता है कि किसी दूसरे number से पूरा divide होता है या नहीं
Types और aliases
- Pretty C, C types के लिए छोटे type aliases देता है
stringयानीchar*byteयानीcharbytesयानीchar*anyयानीvoid*- integer short forms के रूप में
uchar,ushort,uint,ulongदेता है
- Lua और Lisp से प्रभावित syntax aliases भी शामिल हैं
eq,is:==bitnot,bitxor: bit-operation aliasessuccess,fail,failure:success == 0pattern के aliasesbelow,above,upto,downto: comparison operatorseven,odd,positive,negative,zero,empty: numbers और data predicatesnil:NULLuntil: negativewhileelif:else ififnt,elifnt:if(!...)style expressionsrepeat: Lua-styledoaliasdone,finish,pass:break,continuealiasesalways,forever,loop,indefinitely: infinite-loop expressionsnever,comment: ऐसे expressions जिनसे code execute नहीं होता, फिर भी compiler उसे analyze कर सकता है
Type inference, output, comparison, ternary expressions
- Type inference GCC, Clang या C23+ में इस्तेमाल की जा सकती है
- उदाहरण के तौर पर
var t = time(0);,let lt = localtime(&t);,local at = asctime(lt);जैसी forms देता है
- उदाहरण के तौर पर
- Generic output C11+ में इस्तेमाल किया जा सकता है
printदिए गए value को output करता हैprintlnoutput के बाद newline जोड़ता है
- Generic equality comparison भी C11+ feature के रूप में दिया गया है
equal("NA", line)जैसी string comparisonequal(0.3, 0.2 + 0.1)जैसा comparison example शामिल है
- Ternary operator को text-based macros से ज्यादा readable बनाया जा सकता है
whenreadability के लिए empty string में expand होता हैunlessnotमें expand होकरwhenके negative form की तरह काम करता हैthenयानी?otherऔरotherwiseयानी:onlyतब इस्तेमाल होता है जबotherwiseclause की जरूरत नहीं होतीotherwhenअगली condition जोड़ने के लिए इस्तेमाल होता है
Iteration macros
- Pretty C अक्सर इस्तेमाल होने वाले
forloop patterns को macros से abstract करता है foreach (var, type, length, ...)- array या memory region पर iterate करता है
- हर iteration में
varउस array element का pointer बनता है - pointer होने के कारण जरूरत पड़ने पर element को in-place modify किया जा सकता है
forthese (var, type, ...)- दिए गए variadic arguments पर iterate करता है और हर value को
typeकेvarसे bind करता है
- दिए गए variadic arguments पर iterate करता है और हर value को
fortimes (var, times)- 0 से positive count तक repeat करने वाले common pattern को छोटा करता है
forrange (var, init, target)initसेtargetतक numeric range पर iterate करता हैinitऔरtargetकोई भी signed या unsigned integer हो सकते हैं- अगर
init,targetसे बड़ा है तो iteration step घटता है
forrangeby (var, type, init, target, by)- specified
typeवालेvarकोinitसेtargetतकbyinterval में iterate करता है
- specified
Allocation और block utilities
- Allocation macros C++ से प्रभावित रूप में common memory allocation patterns को simplify करते हैं
new (type, ...): C++newजैसी form में structs आदि बनाता हैvector (length, type, ...): specified length और type की array allocate करने और initial contents डालने के pattern को simplify करता हैdelete (...):freeजैसा ही है, लेकिन C++-style नाम पसंद हो तो इस्तेमाल किया जा सकता है
- Block utilities local binding, deferred execution और block-level work के लिए macros देते हैं
lambda (ret, name, ...): GCC, Clang या C++ में nested functions, lambdas, closures जैसी forms को C में इस्तेमाल करने देता हैwith (var, close, ...): resource release functioncloseपहले से देकर dynamically allocated objects या file handles के लिए उपयोगी है- कमी यह है कि bound
varvoid *होता है, इसलिए इस्तेमाल से पहले उसे desired type में convert करना पड़ सकता है
- कमी यह है कि bound
defer: हटा दिया गया है, और नए उपलब्धdeferका इस्तेमाल करने के लिए guide करता हैtryऔरcatch: C में error handling को ज्यादा elaborate रूप में लिखने देता हैNOERR,NOERROR: error switch-case convenience के लिए दिए गए हैं
Contribution का तरीका
- function जोड़ते समय Linux Kernel Style Guide follow करने का अनुरोध है
- commit से पहले
make indentचलाने की सिफारिश है
- commit से पहले
- A’s Commit Message Guide follow करना preferred है, लेकिन required नहीं
1 टिप्पणियां
Hacker News की राय
C के अंदर domain-specific language बनाने की परंपरा काफी पुरानी है
Stephen Bourne shell को ALGOL की तरह लिखना चाहते थे, इसलिए उन्होंने C preprocessor को लगातार इतना पीटा कि वह आखिरकार उनकी पसंदीदा भाषा जैसा दिखने लगा
https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh...
https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh...
https://www.ioccc.org/
सोच रहा हूं कि कोई समझा सकता है क्या कि यह मजाक है, या लेखक सच में उलझा हुआ है
कुछ भी समझ में नहीं आता। यह “scripting” भी नहीं है, “strong typing” लाने की बात करता है लेकिन types के साथ कुछ नहीं करता, और Lua तथा Lisp से प्रेरित बताए गए operator aliases असल में उन दोनों भाषाओं में कहीं नहीं हैं। फिर भी यह साफ-साफ parody जैसा भी नहीं दिखता, इसलिए वाकई उलझन होती है
यह खुद को scripting language कहता है, लेकिन program अब भी compile करना पड़ता है। हूट करने लायक है
CINT(https://root.cern.ch/root/html534/guides/users-guide/CINT.ht...) जोड़ दें तो तुरंत execution और REPL भी संभव है
पहले मैंने एक blog post देखी थी जिसमें
./fooकैसे काम करता है और ELF file कैसे execute होती है, यह विस्तार से बताया गया था। उसी तरीके से.cprograms को register करके compile के बाद run कराया जा सकता है[0] https://gist.github.com/jdarpinian/1952a58b823222627cc1a8b83...
[0] https://bellard.org/tcc/tcc-doc.html
“C developers को diabetic heart attack दिला देने जितनी syntactic sugar देता है।”
यह line मुझे बहुत पसंद आई
CNoEvil[0] और ogw[1] में जोड़ने लायक कुछ चीजें दिख रही हैं। लगता है हर कुछ महीनों में जब यह project फिर ऊपर आता है, हमेशा और चीजें मिल जाती हैं
[0] https://git.sr.ht/~shakna/cnoevil3/
[1] https://git.sr.ht/~shakna/ogw
यह ऐसा वाक्य है जिससे सचमुच दिल की गहराई से प्यार हो जाता है
यह Python 2 जैसी ही गलती कर रहा है। strings और bytes एक ही type नहीं हैं, और उन्हें ऐसा treat भी नहीं करना चाहिए
argvमें मौजूद values या child process output का type क्या माना जाना चाहिए?उसमें कोई भी random garbage value आ सकती है, इसलिए वह valid UTF-8 string नहीं है, लेकिन awk और grep जैसे tools हर जगह इस्तेमाल होते हैं
strings और bytes को एक ही general type माना जा सकता है, बस कभी-कभी valid UTF-8 bytes को internally अलग type देना उपयोगी होता है। Rust इस हिस्से को OsString और String से काफी अच्छी तरह handle करता है
https://en.cppreference.com/w/c/string/multibyte
इनमें से कोई भी बात हमेशा सच नहीं है। validated byte sequence को ऐसे type में wrap करना उपयोगी है जिसे केवल validation के जरिए बनाया जा सके, लेकिन ऐसा करने के बाद
Utf8StringऔरEmailAddressमूल रूप से एक ही category के हो जाते हैं। type system में सिर्फ encoding को special treatment देने की कोई वजह नहीं हैअगर उसका मतलब “इंसान द्वारा पढ़ा जा सकने वाला text” है, तो मैं सहमत हूं कि string किसी arbitrary byte array के समान नहीं है। लेकिन कई languages इस definition को enforce नहीं करतीं
पहले एक C++ codebase याद आया जिसकी मुझे जाँच करनी पड़ी थी। पूरा ऐसा बना था जैसे Java में लिखा गया हो: हर चीज़ में camelCase, हर class variable के लिए getter/setter, और जगह-जगह interfaces थे
https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd...
यकीन करना मुश्किल है कि यह ALGOL नहीं है
std::stringको wrap करती थी, लेकिन उस पर Java-style methods लगाए गए थेhttps://learn.microsoft.com/en-us/cpp/cpp/property-cpp?view=...
f(String *)के रूप में pass किया जाता था, इसलिए C++ codef(new String("Hello")जैसा थाअगर यह दिलचस्प लग रहा है, तो आपको libcello.h भी पसंद आ सकता है
https://www.libcello.org
type names अच्छे हैं, और
minजैसे built-in function macros का चुनाव भी बिल्कुल सही है।Lenभी पसंद आयानाम वाले boolean operators शायद थोड़ा ज़्यादा हो सकते हैं, लेकिन आज़माने लायक हैं, और ternary operator वैसे भी पढ़ने में मुश्किल होता है, इसलिए उसमें सुधार की काफी गुंजाइश है। सभी loop definitions को लेकर मैं पूरी तरह convinced नहीं हूँ, लेकिन कुछ समझ में आते हैं। resource tracking प्रभावशाली है, और
for...वाला रूप थोड़ा भद्दा है, इसलिए शायद उसे कोई और नाम दिया जा सकता हैकुल मिलाकर यह काफी मजबूत प्रयास है। design को मैं लगभग 8/10 देना चाहूँगा। C macros से sketch किया गया तरीका सचमुच elegant है और असल में अच्छे code जैसा दिखता है। मैं खुद इस्तेमाल करूँगा या नहीं, पता नहीं। यह एक नई language है और मुझे पहले से C पसंद है। फिर भी implementation बहुत साफ़ है, इसलिए यह लोगों को C सीखने और language design पर सोचने में मदद कर सकता है
len(),max/min, और कुछ operator macros ही इस्तेमाल करते हैं। क्योंकि अभी बाकी स्वादिष्ट features की ज़्यादा ज़रूरत नहीं पड़ी। इसलिए कम से कम कुछ operator macros आज़माकर देखना अच्छा रहेगाif(!...)के लिएifntकी बात हो, तो unless मुझेifntसे ज़्यादा readable लगता हैfor(;;)loop कोalwaysकहना भी हैदूसरी languages में मैंने
loopदेखा है। लेकिन Qt इसेforeverकहता है, और यह सच में सुंदर है। बहुत Qt जैसा भी हैifntको ज़ोर से बोलने पर मज़ा आता हैunlessको ternary condition के लिए बचाकर रखा था। क्योंकि वह वहाँ किसी भी तरह ज़्यादा उपयोगी हैअरे, ठहरो, यह तो John Tromp हैं। BLC बनाने वाले! मैं fan हूँ