एक प्रोग्रामिंग भाषा में एक सुविधा जोड़ें [बंद]


55

आपका कार्य किसी प्रोग्रामिंग लैंग्वेज के लिए एक फ़ीचर से निपटना है, या तो बहुत ही चतुर लाइब्रेरी को लागू करके, या इनपुट टेक्स्ट को प्रोसेस करके और / या संकलन प्रक्रिया को ट्विक करके।

विचार:

  • सी (जैसे <?c printf("Hello,"); ?> world!) के लिए PHP- शैली प्रस्तुति interleaving जोड़ें ।
  • उन भाषाओं में से एक के लिए एक नल coalescing ऑपरेटर जोड़ें जो C # नहीं है।
  • PHP में macros जोड़ें।
  • gotoजावास्क्रिप्ट में जोड़ें ।
  • भाषा X से मेल खाते हुए पैटर्न जोड़ें।
  • उस भाषा में नामस्थान समर्थन जोड़ें जिसमें यह नहीं है।
  • बनाओ सी PHP की तरह लग रहे हो।
  • हास्केल को पास्कल की तरह बनाएं।
  • ... (टिप्पणी अनुभाग में विचारों को पोस्ट करने के लिए स्वतंत्र महसूस करें)

नियम:

  • मेज पर कुछ लाओ। हास्केल में मेटाप्रोग्रामिंग सुविधाओं को जोड़ने के लिए सिर्फ "टेम्पलेट हास्केल" न कहें। यह StackOverflow नहीं है।
  • संपूर्ण कार्यान्वयन एक स्क्रीनफुल (उदाहरण की गिनती नहीं) में फिट होना चाहिए।
  • विशेष रूप से इस कार्य के लिए किसी बाहरी साइट पर कोड होस्ट न करें।
  • सबसे प्रभावशाली या आश्चर्यजनक फीचर जीतता है।

100% सुविधा को सही तरीके से लागू करने की चिंता न करें। इससे दूर! मुख्य चुनौती यह पता लगाना है कि आप क्या करना चाहते हैं और शातिर तरीके से विवरण काट रहे हैं जब तक कि आपके नियोजित उपक्रम संभव नहीं हो जाते।

उदाहरण:

C प्रोग्रामिंग भाषा में एक लैम्ब्डा ऑपरेटर जोड़ें ।

प्रारंभिक दृष्टिकोण:

ठीक है, मुझे पता है कि मैं libgc का उपयोग करना चाहता हूं, इसलिए मेरा लंबोदर ऊपर और नीचे की फंगर समस्याओं को हल करेगा। मुझे लगता है कि पहली चीज जो मुझे करने की ज़रूरत है वह सी प्रोग्रामिंग भाषा के लिए एक पार्सर लिखना / खोजना है, फिर मुझे सी के प्रकार प्रणाली के बारे में सब सीखना होगा। मुझे यह पता लगाना होगा कि इसके प्रकार के बारे में कैसे जाना जाए। क्या मुझे टाइप इंट्रेंस लागू करने की आवश्यकता होगी, या क्या मुझे केवल औपचारिक पैरामीटर को दिए जाने की आवश्यकता होगी? CI में उन सभी पागल सुविधाओं के बारे में अभी तक क्या पता नहीं है?

यह स्पष्ट है कि सी में लंबोदर को सही ढंग से लागू करना एक बहुत बड़ा उपक्रम होगा। शुद्धता के बारे में भूल जाओ! सरलीकृत करें, सरल करें।

बेहतर:

पेंच ऊपर की ओर, जो उन्हें जरूरत है? मैं GNU C के नेस्टेड फ़ंक्शन और स्टेटमेंट एक्सप्रेशन के साथ कुछ मुश्किल कर सकता हूं । मैं सी, ट्रिक, हैकी कोड के साथ सी पर एक अद्भुत वाक्यात्मक परिवर्तन दिखाना चाहता था, लेकिन मुझे इसके लिए किसी पार्सर की भी आवश्यकता नहीं होगी। वह एक और दिन इंतजार कर सकता है।

परिणाम (जीसीसी की आवश्यकता है):

#include <stdio.h>
#include <stdlib.h>

#define lambda(d,e)({d;typeof(e)f(d){return(e);};f;})

#define map(F,A)({typeof(F)f=(F);typeof(*(A))*a=(A);({int i,l=((int*)(a))[-1]; \
typeof(f(*a))*r=(void*)((char*)malloc(sizeof(int)+l*sizeof(*r))+sizeof(int));  \
((int*)r)[-1]=l;for(i=0;i<l;i++)r[i]=f(a[i]);r;});})

#define convert_to(T) lambda(T x, x)
#define print(T, fmt) lambda(T x, printf(fmt "\n", x))

int main(void)
{
    int *array = 1 + (int[]){10, 1,2,3,4,5,6,7,8,9,10};
    map(print(int, "%d"), array);

    double *array2 = map(lambda(int x, (double)x * 0.5), array);
    map(print(double, "%.1f"), array2);

    long *array3 = map(convert_to(long), array2);
    map(print(long, "%ld"), array3);

    long product = 1;
    map(lambda(int x, product *= x), array);
    printf("product: %ld\n", product);

    return 0;
}

यह आसान था, है ना? मैं भी mapइसे उपयोगी और सुंदर बनाने के लिए एक मैक्रो में फेंक दिया ।


10
मुझे लगता है कि केन थॉम्पसन ने हम सभी को हराया : 0 बाइट्स ऑफ़ कोड।
dmckee

4
मैं पूर्ण उत्तर नहीं बनाना चाहता, लेकिन मैंने किसी को दिलचस्पी होने की स्थिति में जीएनयू सी में कक्षाएं जोड़ दी हैं
रिचर्ड जे रॉस III

3
निश्चित नहीं है कि यह योग्य है, लेकिन मैंने सी में जारी रहने का एक उदाहरण लिखा है । एक पटकथा से थोड़ा अधिक, यद्यपि।
लूसर डॉग

1
मेरा धन्यवाद जिसने भी इस प्रश्न को पुनर्जीवित किया; मेरे पास मेरे प्रस्तुत करने के लिए एक उत्कृष्ट विचार है।
जोनाथन वान माट्रे

2
सी के लिए एक मेमने जोड़ें ... अरे मुझे उस तरह मत देखो।
लेउशेंको

जवाबों:


27

हास्केल में OOP सिंटैक्स

import Prelude hiding ((.))
a . b = b a

वस्तुओं में गुण हो सकते हैं:

[1,5,3,2].length -- 4
[1,5,3,2].maximum -- 5
'a'.succ -- 'b'

... और तरीके:

"Hello world!".take(5) -- "Hello"
"Hello world!".splitAt(2) -- ("He","llo world!")
"Hello world!".map(toUpper) -- "HELLO WORLD!"

2
कहीं मैंने इस ऑपरेटर को इस &तरह लिखा और परिभाषित किया (&) = flip ($)
बेंत की मार

6
@swish मैंने उपयोग नहीं किया &क्योंकि यह 'एड्रेस-ऑफ' एकरी ऑपरेटर है (हास्केल में पॉइंटर्स का कार्यान्वयन पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है)।
lortabac

1
@ आपके द्वारा एक चरित्र (और एक मस्तिष्क-चक्र) को बचाकर उपयोग किया जा सकता हैflip id
शॉन डी

24

goto जावास्क्रिप्ट में

मेरा पहला विचार एक कार्यात्मक दृष्टिकोण था - फ़ंक्शन को एक पैरामीटर जोड़ने के लिए इंगित करने के लिए कि निष्पादन कहां शुरू होना चाहिए, एक switchबयान और बाहरी लूप के साथ बार-बार फ़ंक्शन को अपने स्वयं के रिटर्न मूल्य पर कॉल करना । दुर्भाग्य से, यह स्थानीय चर के उपयोग को रोक देगा, क्योंकि वे हर गोटो के साथ अपने मूल्यों को खो देंगे।

मैं एक withबयान का उपयोग कर सकता हूं और फ़ंक्शन की शुरुआत में सभी चर घोषणाओं को स्थानांतरित कर सकता हूं , लेकिन एक बेहतर तरीका होना चाहिए। यह अंततः जावास्क्रिप्ट के अपवाद हैंडलिंग का उपयोग करने के लिए मेरे पास आया । वास्तव में, जोएल स्पोल्स्की ने कहा, "मैं अपवादों को" गोटो ... ... "से बेहतर नहीं मानता

यह विचार एक फ़ंक्शन के अंदर एक अनंत लूप लगाने के लिए था, केवल एक returnबयान या एक अनकहा अपवाद द्वारा समाप्त किया गया था। अपवाद के रूप में व्यवहार किए गए सभी गोटो को समाप्त होने से रोकने के लिए लूप के भीतर पकड़ा जाएगा। यहाँ उस दृष्टिकोण का परिणाम है:

function rewriteGoTo(func) {
    var code = '(';
    code += func.toString()
        .replace(/^\s*(\w+)\s*:/gm, 'case "$1":')
        .replace('{', '{ var $_label = ""; function goTo(label) { $_label = label; throw goTo; } while(true) try { { switch($_label) { case "": ');
    code += '} return; } catch($_e) { if($_e !== goTo) throw $_e; } })';
    return code;
}

आप इसे इस तरह से उपयोग कर सकते हैं - यहां तक ​​कि ईएस 5 सख्त मोड में भी - इंटरनेट एक्सप्लोरर ( डेमो ) को छोड़कर :

var test = eval(rewriteGoTo(function(before) {
    var i = 1;
    again: print(before + i);
    i = i + 1;
    if(i <= 10) goTo('again');
}));

[इंटरनेट एक्सप्लोरर, किसी कारण से, एक अनाम फ़ंक्शन के कोड को विकसित करने में विफल रहता है, इसलिए किसी को फ़ंक्शन को एक नाम देना होगा (पुनर्लेखन से पहले) और उस नाम का उपयोग करके इसे कॉल करना होगा। बेशक, यह शायद सख्त मोड के नियमों को तोड़ देगा।]

यह एक ब्लॉक के भीतर स्थित एक बयान में कूदने की अनुमति नहीं देता है (जब तक कि डफ के उपकरण के रूप में इस तरह के निर्माण कानूनी नहीं हो जाते हैं), लेकिन हम इससे (एक और, स्व-निष्पादित पुनर्लेखन समारोह), सही से निपट सकते हैं?


1
मिठाई! इसे सरल रखते हुए अच्छा काम। ट्रिविया का एक दिलचस्प बिट: यदि gotoपूरी तरह से जावास्क्रिप्ट में लागू किया गया था (जहां आप gotoकिसी भी दायरे, यहां तक ​​कि एक फ़ंक्शन से बाहर कूदने के लिए उपयोग कर सकते हैं ), तो यह निरंतरता के लिए समर्थन करेगा।
जॉय एडम्स

22

जावा में #define

मैंने सोचा कि जावा में मैक्रोज़ को लागू करना मजेदार होगा।

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * defines the use of #define. Usage:
 *
 * #def toReplaceCanHaveNoSpaces replacement can have extra spaces
 *
 * must be at the beginning of the line (excluding starting spaces or tabs)
 * 
 * @author Quincunx
 */
public class Define {

    public static void main(String[] args) {
        if (args.length != 1) {
            err("Please provide exactly 1 argument");
        }
        File source = new File(args[0]);
        if (!source.exists()) {
            err("Supplied filepath does not point to an existing file");
        }
        if (!getExtension(args[0]).equalsIgnoreCase(".java")) {
            err("Supplied file is not of type .java");
        }
        ArrayList<String> sourceData = new ArrayList<>();
        ArrayList<String[]> replacements = new ArrayList<>();
        try {
            BufferedReader read = new BufferedReader(new FileReader(source));
            String data;
            while ((data = read.readLine()) != null) {
                sourceData.add(data);
            }
            read.close();
        } catch (IOException ex) {
            Logger.getLogger(Define.class.getName()).log(Level.SEVERE, null, ex);
        }
        for (int index = 0; index < sourceData.size(); index++) {
            String line = sourceData.get(index);
            line = line.replaceAll("\t", "    ");
            for (String[] e : replacements) {
                line = line.replace(e[0], e[1]);
            }

            if (line.trim().charAt(0) != '#') {
                sourceData.set(index, line);
                continue;
            }
            while (line.charAt(0) != '#') {
                line = line.substring(1);
            }
            int indexOf = line.indexOf(" ");
            String type = line.substring(1, indexOf);

            switch (type) {
                case "def":
                case "define":
                    String toReplace = line.substring(indexOf + 1, line.indexOf(" ", indexOf + 1));
                    replacements.add(new String[]{toReplace, line.substring(line.indexOf(":") + 1)});
                    break;
                default:
                    err("The source code contains a # in which there is no correct type");
            }
        }

        try {
            BufferedWriter write = new BufferedWriter(new FileWriter(source));
            for (String s : sourceData) {
                write.write(s);
                write.newLine();
            }
            write.close();
        } catch (IOException ex) {
            Logger.getLogger(Define.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void err(String message) {
        System.err.println(message);
        System.exit(1);
    }

    public static String getExtension(String filePath) {
        return filePath.substring(filePath.lastIndexOf("."));
    }

}

नमूना उपयोग (पहले पोस्ट किए गए कोड में कनवर्ट करता है; चलिए इसे अजीब बनाते हैं):

#def @ o
#def ~ a
#def $ i
#def ` e
#d`f % m
#d`f ! {
#d`f & d
#&`f _ }
#&`f 2 (
#&`f 7 )
#&`f $%p@rt$@. $%p@rt j~v~.$@.
#&`f $%p@rtu. $%p@rt j~v~.ut$l.
#&`f ps publ$c st~t$c
#&`f Str Str$ng

$%p@rt$@.Buff`r`&R`~&`r;
$%p@rt$@.Buff`r`&Wr$t`r;
$%p@rt$@.F$l`;
$%p@rt$@.F$l`R`~&`r;
$%p@rt$@.F$l`Wr$t`r;
$%p@rt$@.IOExc`pt$@n;
$%p@rtu.Arr~yL$st;
$%p@rtu.l@gg$ng.L`v`l;
$%p@rtu.l@gg$ng.L@gg`r;

#d`f L$st Arr~yL$st
#d`f l@g; L@gg`r.g`tL@gg`r2D`f$n`.cl~ss.g`tN~m`277.l@g2L`v`l.SEVERE, null, `x7;    

publ$c cl~ss D`f$n` !

    ps v@$d %ain2Str[] ~rgs7!
        $f 2~rgs.l`ngth != 17 !
            `rr2"Pl`~s` pr@v$&` `x~ctly 1 ~rgu%`nt"7;
        _
        F$l` squrc` = n`w F$l`2~rgs[0]7;
        $f 2!sourc`.`x$sts277 !
            `rr2"Suppli`& f$l`p~th &@`s n@t p@int t@ ~n `x$st$ng f$l`"7;
        _
        $f 2!g`tExt`ns$@n2~rgs[0]7.`qu~lsIgn@r`C~s`2".j~v~"77 !
            `rr2"Suppl$`& f$l` $s n@t @f typ` .j~v~"7;
        _
        L$st<Str> s@urceDat~ = n`w List<>27;
        L$st<Str[]> repl~cem`nts = n`w L$st<>27;
        try !
            Buff`r`&R`a&`r r`a& = new Buff`redRe~&`r2n`w F$l`R`~&`r2s@urc`77;
            Str &~t~;
            wh$l` 22&~t~ = r`~&.r`~&L$n`277 != null7 !
                s@urc`D~t~.~&&2&ata7;
            _
            re~&.cl@se27;
        _ c~tch 2IOExc`ption ex7 !
            log;
        _
        f@r 2$nt $n&`x = 0; $ndex < s@urc`D~t~.s$z`27; $nd`x++7 !
            Str l$n` = s@urc`D~ta.get2index7;
            line = line.r`pl~c`All2"\t", "    "7;
            for 2Str[] ` : r`pl~c`%`nts7 {
                line = line.r`pl~c`2`[0], e[1]7;
            _

            if 2l$ne.tr$%27.ch~rAt207 != '#'7 !
                sourc`D~t~.s`t2$n&`x, l$n`7;
                c@nt$nu`;
            _
            wh$l` 2line.ch~rAt207 != '#'7 !
                l$ne = l$ne.substr$ng217;
            _
            $nt in&`xOf = line.$n&`xOf2" "7;
            Str typ` = line.substring21, indexOf7;

            sw$tch 2type7 !
                c~s` "&`f":
                c~s` "def$n`":
                    str t@R`pl~c` = line.substring2indexOf + 1, line.indexOf2" ", indexOf + 177;
                    r`pl~c`%`nts.~&&2n`w s\Str[]!t@R`place, line.substring2line.indexOf2":"7 + 17_7;
                    br`~k;
                def~ult:
                    err2"Th` s@urc` c@&` c@nt~$ns ~ # $n wh$ch th`r` i$s n@ c@rr`ct typ`"7;
            _
        _

        try !
            Buff`r`&Wr$ter wr$te = new BufferedWriter2new F$l1Wr$t1r2s@urc177;
            for 2Str s : s@urceData7 !
                wr$te.write2s7;
                wr$te.n`wLin`27;
            _
            wr$t`.cl@s`27;
        _ c~tch 2IOExc`pt$@n `x7 !
            l@g;
        _
    _

    ps v@$& `rr2Str m`ss~g`7 !
        Syst`%.`rr.pr$ntln2message7;
        Syst`%.`x$t217;
    _

    ps Str g`tExt`nsi@n2Str fileP~th7 !
        r`turn f$lePath.substr$ng2f$l`P~th.l~stInd`xOf2"."77;
    _

_

7
मैं दूसरे ब्लॉक के माध्यम से स्क्रॉल कर रहा था, और मेरा एकमात्र विचार था "... खरगोश छेद नीचे।"
सोहम चौधरी

18

सी में फोरच

Iterate सरणियाँ (स्थिर सरणियों के लिए कार्य करता है, न कि सूचक के माध्यम से प्राप्त)

//syntactic beauty
#define in ,    

//syntactic beauty's helper macro
#define foreach(a) _foreach(a)

//the real foreach macro
#define _foreach(e,arr)\
typeof (&arr[0]) e;\
for (e=&arr[0];e!=&arr[sizeof(arr)/sizeof(arr[0])];e++)

इसका परीक्षण करने के लिए:

int int_arr[3]={10,20,30};    
char *strings[]={"Hello","World","Foreach","Test"};

foreach (num in int_arr) {
        printf ("num=%d\n",*num);
}

foreach (str in strings) {
        printf ("str=%s\n",*str);
}

नतीजा:

num=10
num=20
num=30
str=Hello
str=World
str=Foreach
str=Test

17

सी में गुण

टॉमस व्रेंजज़ोव्स्की ने संपत्ति के एक्सेस होने पर प्रोग्राम को जानबूझकर सीगफॉल्ट करके, सादे सी में गुणों को लागू किया

एक "संपत्ति" के साथ एक ऑब्जेक्ट structकई पृष्ठों को पार करके बनाया जाता है, यह सुनिश्चित करता है कि संपत्ति का मेमोरी पता वास्तविक डेटा सदस्यों से अलग पेज में है। संपत्ति के पृष्ठ को नो-एक्सेस के रूप में चिह्नित किया गया है, यह गारंटी देता है कि संपत्ति तक पहुंचने का प्रयास एक segfault का कारण होगा। एक गलती हैंडलर तब पता लगाता है कि किस संपत्ति की पहुंच सेगफॉल्ट का कारण बनी, और संपत्ति के मूल्य की गणना करने के लिए उपयुक्त फ़ंक्शन को कॉल करता है, जो संपत्ति के मेमोरी पते पर संग्रहीत होता है।

गलती हैंडलर भी डेटा पृष्ठ को केवल-पढ़ने के लिए चिह्नित करता है ताकि यह सुनिश्चित किया जा सके कि संगणित मूल्य सुसंगत रहे; जब आप अगली बार एक डेटा सदस्य को लिखने की कोशिश करते हैं, जो एक segfault को ट्रिगर करता है, जिसके हैंडलर ने डेटा पेज को रीड-राइट और प्रॉपर्टी पेज को नो-एक्सेस के रूप में सेट किया है (यह दर्शाता है कि इसे पुनर्संयोजित करने की आवश्यकता है)।


15

कॉमन लिस्प में कंप्यूटेड कम-से-कम

मैंने शुरू से लागू किया। लेकिन यह काफी अच्छा नहीं था।

गणना गोटो से प्रेरित होकर, मैंने कम्प्यूटेड को लागू करने का निर्णय लिया।

(defmacro computed-come-from-tagbody (&rest statements)
  (let ((has-comp-come-from nil)
        (comp-come-from-var nil)
        (start-tag (gensym))
        (end-tag (gensym)))

    (let ((current-tag start-tag)
          (come-froms (make-hash-table :test #'eq)))

      (let ((clauses '()))
        (loop for statement in statements do
             (if (symbolp statement)
                 (setf current-tag statement))

             (cond
               ((and (consp statement)
                     (eql 'come-from (car statement)))

                (setf has-comp-come-from t)
                (setf (gethash (cadr statement) come-froms) current-tag))
               (t (push statement clauses))))


        (if (not has-comp-come-from)
            `(tagbody ,@(reverse clauses))
            (let ((res '())
                  (current-tag start-tag))
              (loop for clause in (reverse clauses) do
                   (cond
                     ((symbolp clause)
                      (push clause res)
                      (setf current-tag clause)
                      ;; check all vars for jumps
                      (push
                       `(progn ,@(loop for k being the hash-key of come-froms
                                    for v being the hash-value of come-froms collect
                                      `(when (eql ,k ,current-tag)
                                         (go ,v))))
                       res))
                     (t (push clause res))))
              `(macrolet ((come-from (idx)
                            (declare (ignore idx))
                            (error "Come-from cannot be used with another form.")))
                 (tagbody ,@(reverse res)))))))))

उपयोग के उदाहरण

(come-from x) ; whenever we're at the top of a labeled block and the value of x is equal to the label, jump back to this point.

टैगबॉडी में प्रत्येक आने-जाने की घोषणा के लिए, यह प्रत्येक लेबल पर जांच करेगा कि क्या आने-वाले चर वर्तमान लेबल के बराबर है, और यदि ऐसा है, तो संबंधित आने-जाने की घोषणा के लिए कूदें।

स्वागतकर्ता

(let ((x :repeat)
      (y :exit))
   (computed-come-from-tagbody
      :loop              ;; when x == :loop jump to :loop.  when y == :loop jump to :exit
      (come-from x)
      (format t "What is your name? ")
      (let ((name (read-line)))
         (terpri)
         (format t "Hello ~a~%" name)
         (print (string= name "exit"))
         (when (string= name "exit")
             (setf x nil
                   y :repeat)))
       :repeat           ;; when x = :repeat jump to loop, when y = :repeat jump to exit
       :exit             ;; when x = :exit jump to loop, when y = :exit jump to exit
       (come-from y)))

FizzBuzz

(let ((i 0)
      (x nil)
      (y nil))
   (computed-come-from-tagbody
       :loop
       (come-from x)
       (cond
         ((> i 100)  (setf x nil
                           y :end-iteration)) 
         (t (or (and (zerop (mod i 3)) (zerop (mod i 5)) (print "FizzBuzz"))
                (and (zerop (mod i 3)) (print "Fizz"))
                (and (zerop (mod i 5)) (print "Buzz"))
                (print i))  
            (incf i)
            (setf x :end-iteration)))
       :end-iteration
       :end
       (come-from y)
       (print "done")))

14

रूबी में "ऑटो-स्ट्रिंग्स"

कोड काफी सरल है:

def self.method_missing *a; a.join ' '; end

अब आप कर सकते हैं

print This is an automatic string #=> This is an automatic string
print hooray #=> hooray

x = code golf
print This is + ' ' + x + '!' #=> This is code golf!


13

PHP में macros जोड़ें

हम इस कार्य के लिए बस C प्रीप्रोसेसर का उपयोग कर सकते हैं।

एक php स्क्रिप्ट:

<?php

#define ERROR(str) trigger_error(#str, E_USER_ERROR)

function test() {
        ERROR(Oops);
}

पाइप इसे हालांकि cpp:

cpp < test.php

नतीजा:

<?php

function test() {
 trigger_error("Oops", E_USER_ERROR);
}

PHP सुविधाओं के साथ ब्रेक नहीं होगा जो C में मौजूद नहीं है? इस तरह के heredocs के रूप में। अफेयर द सी पीपी बहुत कसकर सी के व्याकरण से बंधा था।
जॉय

1
मुझे लगता है कि प्रीप्रोसेसर केवल इस अर्थ को बनाने की कोशिश किए बिना इनपुट का उपयोग करता है। एक <<<HEREDOCसे कम या बाएँ पारी और पहचानकर्ता :-) यह हियरडॉक तार में वृहद प्रतिस्थापन करना होगा, फिर भी 3 से ज्यादा कुछ नहीं है।
अरनौद ले ब्लांक

सी प्रीप्रोसेसर आउटपुट में अतिरिक्त कचरा जोड़ता है, इसलिए आपका उदाहरण उम्मीद के मुताबिक काम नहीं करेगा
अनाम कायर

1
एक grep -v ^#फुसफुसाया कि ठीक। मुझे लगता है कि यह इस सवाल के लिए पर्याप्त है :-)
अरनौद ले ब्लैंक

10

पायथन में पैटर्न मिलान गार्ड

def pattern_match(n, s="__fns"):
 s=n+s;g=globals()
 def m(f):
  def a(*r):
   for f in g[s]:
    if reduce(lambda c,t:c and eval(t[1:],{},dict(zip(f.func_code.co_varnames,r))),filter(lambda x:x and x[0]is"|",map(lambda x:x.strip(),f.func_doc.split("\n")))): return f(*r)
  g[n]=a;g[s]=(g.get(s)or[])+[f]
  return a
 return m

फ़ंक्शन का मुख्य भाग 288 वर्णों पर आता है।

पैटर्न मिलान गार्ड आपको तर्क मूल्यों के आधार पर पूरी तरह से अलग कार्यों का उपयोग करने की अनुमति देते हैं। यद्यपि यह आसानी से ifबयानों की एक श्रृंखला के साथ अनुकरण किया जा सकता है , पैटर्न से मेल खाने वाले गार्ड कोड के अलग-अलग वर्गों की मदद कर सकते हैं, और यह कुछ पागल मेटाप्रोग्रामिंग करने के लिए एक महान बहाना है।

pattern_matchएक डेकोरेटर है जो एक नया फ़ंक्शन बनाता है जो गार्ड से मेल खाते पैटर्न को लागू करता है । एक पाइप ( |) से शुरू होने वाली लाइनों पर प्रत्येक डॉकस्ट्रिंग में दिए गए प्रत्येक "उप-फ़ंक्शन" के लिए शर्तें । यदि सभी स्थितियां सत्यता का मूल्यांकन करती हैं, तो फ़ंक्शन का वह संस्करण चलाया जाता है। जब तक कोई मैच नहीं मिलता तब तक फंक्शंस का परीक्षण किया जाता है। अन्यथा, Noneवापस कर दिया जाता है।

एक उदाहरण स्पष्ट करने में मदद करेगा:

@pattern_match("test1")
def test1_a(a, b, c):
    """
    This guard tests if a and c are positive

    | a > 0
    | c > 0
    """
    return a + b + c

@pattern_match("test1")
def test1_b(a, b, c):
    """
    This pattern only ensures b is positive

    | b > 0
    """
    return b + c

@pattern_match("test1")
def test1_c(a, b, c):
    """
    Final catchall

    | True
    """
    return 0


print test1(1,2,3) # (a) >>> 6
print test1(1,2,0) # (b) >>> 2
print test1(1,0,0) # (c) >>> 0
print test1(0,0,1) # (b) >>> 1

हास्केल में, इसे गार्ड कहा जाता है , न कि पैटर्न मिलान। हास्केल में, पैटर्न मिलान आपको कहने देता है f [a,b,c] = ..., जो न केवल एक विधेय के खिलाफ तर्क का परीक्षण करता है, बल्कि यह सफल मैच पर संबंधित चर को बांधता है। यह अभी भी बहुत अच्छा है, हालांकि।
जोए एडम्स

डी 'oy! सही करने के लिए धन्यवाद! मैं हास्केल के बारे में भी सोच रहा था, विशेष रूप से दो अलग अलग विधेय (यानी के साथ एक समारोह को परिभाषित करने पर ध्यान केंद्रित कर f (x:xs) = ...और f [] = ...)। किसी तरह मैंने गार्ड को वहां |से हटा दिया , लेकिन मैं वहीं से ले गया ।
zbanks

यह एक कोड गोल्फ चुनौती नहीं है; यदि आप चाहें तो आप अधिक क्रिया (और पठनीय) हो सकते हैं! :)
रीचार्ल्स

7

coroutine

मैं इसका श्रेय नहीं ले सकता, इसलिए मैंने इसे सीडब्ल्यू चिह्नित किया है।

सी । साइमन ताथम द्वारा कोराउटाइन


7

कस्टम ऑपरेटर लुआ में

कस्टम इन्फिक्स ऑपरेटरों को परिभाषित करने की अनुमति देने के लिए लुगा में ओवरलोडिंग के कारण पोग्स ने चतुराई से दुरुपयोग किया। मैंने इसे ऑपरेटर सेक्शनिंग का समर्थन करने के लिए विस्तारित किया है (आंशिक रूप से ऑपरेटर के साथ एक ऑपरेटर को लागू करना) और परिणामस्वरूप ऑब्जेक्ट को कॉल करना जैसे कि यह एक फ़ंक्शन था।

---- implementation
function infix(f)
  local function g(self, x)
    return f(self[1] or x, self[2] or x)
  end

  local mt   = { __sub = g, __call = g }
  local self = {}
  return setmetatable(self,
           { __sub = function (lhs,rhs)
                       return rhs == self and setmetatable({ lhs, nil }, mt)
                                           or setmetatable({ nil, rhs }, mt)
                     end })
end

---- testing
local eq   = infix(function (a, b) return a == b end)
local ge   = infix(function (a, b) return a >= b end)

local comp = infix(function (a, b) return a < b and -1
                                       or a > b and  1
                                       or            0 end)

function filter(pred, xs)
  local res = {}
  for i=1,#xs do
    if pred(xs[i]) then table.insert(res, xs[i]) end
  end
  return res
end

print(1  -eq-  1)                                      --> true
print(1 -comp- 0)                                      --> 1
print((4 -ge)(1))                                      --> true
print(table.unpack(filter(ge- 0, {1,-4,3,2,-8,0})))    --> 1   3   2   0

7

जावास्क्रिप्ट में मल्टीलाइन तार

मल्टीलाइन स्ट्रिंग्स के लिए इस विस्तृत सिंटैक्स में, हर मल्टीलाइन स्ट्रिंग के साथ (function(){/*और एक नई रेखा होगी, और उसके बाद एक नई रेखा और */}+'').split('\n').slice(1,-1).join('\n')

इस अद्भुत, सहज ज्ञान युक्त वाक्यविन्यास का उपयोग करते हुए, हम अंत में मल्टीलाइन स्ट्रिंग्स का उपयोग कर सकते हैं:

var string = (function(){/*
THIS IS A MULTILINE STRING
HOORAY!!!
*/}+'').split('\n').slice(1,-1).join('\n');

console.log(string) // THIS IS A MULTILINE STRING
                    // HOORAY!!!

जो लोग हमारे सरल वाक्यविन्यास को पसंद नहीं करते हैं, उनके लिए हमारी शानदार नई भाषा का संकलन है:

function compile(code)
{
    return code.replace("#{", "(function(){/*").replace("}#", "*/}+'').split('\n').slice(1,-1).join('\n')")
}

एक ही उदाहरण, संकलित भाषा संस्करण में:

var string = #{
THIS IS A MULTILINE STRING
HOORAY!!!
}#;
console.log(string) // THIS IS A MULTILINE STRING
                    // HOORAY!!!

1
किसी कारण से मैं */अपने मल्टीलाइन स्ट्रिंग्स में नहीं डाल सकता । यह सुपर कष्टप्रद है जब स्ट्रिंग्स में रीजैक्स शामिल हैं!
FireFly

@ पूरी तरह से, मुझे लगता है कि यह अभी भी काम करता है। सिंटेक्स हाइलाइटिंग हालांकि अजीब हो जाता है।
गर्वित हैकेलर

6

C # में पर्याप्त सूची (जैसे पायथन)

मैंने हमेशा अजगर के स्लाइस नोटेशन का आनंद लिया और काश यह C # में उपलब्ध होता

उपयोग:

SliceList<int> list = new SliceList<int>() { 5, 6, 2, 3, 1, 6 };
var a = list["-1"];     // Grab the last element (6)
var b = list["-2:"];    // Grab the last two elements (1,6)
var c = list[":-2"];    // Grab all but the last two elements (5,6,2,3)
var d = list["::-1"];   // Reverse the list (6,1,3,2,6,5)
var e = list["::2"];    // Grab every second item (5,2,1)

कोड, त्रुटि प्रमाण से दूर:

public class SliceList<T> : List<T>
{
    public object this[string slice]
    {
        get
        {
            if (string.IsNullOrWhiteSpace(slice))
                return this.ToList();
            int[] values = { 0, Count, 1 };
            string[] data = slice.Split(':');
            for(int i = 0; i < data.Length; i++)
            {
                if (string.IsNullOrEmpty(data[i])) continue;
                int value;
                int.TryParse(data[i], out value);
                if(value < 0 && i < 2)
                    value += Count;
                values[i] = value;
            }
            if (data.Length == 1)
                return this[values[0]];
            int start = Math.Min(values[0], values[1]);
            int stop = Math.Max(values[0], values[1]);
            int step = values[2];
            int sign = Math.Sign(step);
            if (sign < 0)
            {
                var temp = start;
                start = stop-1;
                stop = temp-1;
            }

            SliceList<T> newList = new SliceList<T>();
            for (int i = start; i != stop; i += step)
                newList.Add(this[i]);

            return newList;
        }
    }
}

मैंने एक लंबे समय से पहले .NET में शामिल करने का अनुरोध किया था, यह अभी भी अनदेखा है :(
रे

6

सी को सरल बनाओ

यह कोड आपको C प्रोग्राम लिखने की अनुमति देता है जो एक स्क्रिप्टिंग भाषा से मिलता जुलता है। इसमें 'var', 'is', 'string', 'plus', 'बराबर' और कई अन्य जैसे कीवर्ड हैं। यह बहुत सारे परिभाषित कथनों के माध्यम से काम करता है ।

// pretty.c

#include<stdio.h>

#define function int
#define var int
#define is =
#define then {
#define do {
#define does {
#define end }
#define equal ==
#define notequal !=
#define greater >
#define less <
#define greaterequal >=
#define lessequal <=
#define display printf
#define otherwise }else{
#define increase ++
#define decrease --
#define plus +
#define minus -
#define times *
#define divide /
#define character char
#define string char*
#define integer int

यह आपको कोड लिखने की अनुमति देता है जैसे:

/*
Preprocessor abuse, Yay!
*/

#include "pretty.c"

function main() does
    var myVar is 1;
    if(myVar greater 2)then
        display("Yep\n");
    otherwise
        display("Nope\n");
    end

    for(var i is 0; i less 10; i increase)do
        display("Loop: %d\n", i);
    end

    string myString = "Hello";
    display(myString);
end

ऊपर का विस्तार किया गया है:

int main() {
    int myVar = 1;
    if(myVar > 2){
        printf("Yep\n");
    }else{
        printf("Nope\n");
    }

    for(int i = 0; i < 10; i ++){
        printf("Loop: %d\n", i);
    }

    char* myString = "Hello";
    printf(myString);
}

शायद अधिक उपयोगी नहीं है, लेकिन मुझे यह काफी दिलचस्प लगा कि आप अनिवार्य रूप से एस के एक समूह के माध्यम से पूरी प्रोग्रामिंग भाषा बना सकते हैं #define


यह एक जावास्क्रिप्ट / रूबी मैशप की तरह दिखता है ...
बीटा डेके

इसके लिए कोई बहुत ऊपरी सीमा नहीं है - जटिल पर्याप्त #defineएस के साथ, आप अपनी भाषा की चीजों को अपवाद की हैंडलिंग और कचरा संग्रह की तरह भी दे सकते हैं, जबकि अभी भी मौलिक सी परत को नीचे रखते हुए।
लेउशेंको

5

Tcl

Tcl है do ... whileया do ... untilनहीं ...

proc do {body op expr} {
    uplevel 1 $body
    switch -exact -- $op {
        while {
            while {[uplevel 1 [list expr $expr]} {
                uplevel 1 $body
            }
        }
        until {
            while {![uplevel 1 [list expr $expr]} {
                 uplevel 1 $body
            }
        }
    }
}

उदाहरण:

do {
    puts -nonewline "Are you sure? "
    flush stdout
    set result [gets stdin]
} while {[string is boolean -strict $result]}

uplevel कॉलर्स स्कोप में स्क्रिप्ट निष्पादित करता है।


5

पोस्टस्क्रिप्ट में गोटो

मेरा पहला विचार यह था कि मुझे निष्पादन स्टैक के बारे में सोचना होगा, इसलिए यह झूठी शुरुआत भूतहास्क्रिप्ट (या xpost) से रोक के लिए निरंतरता ऑपरेटर को खोदती है।

/_stopped_mark
{countexecstack array execstack dup length 2 sub get}
stopped pop def 

लेकिन, यह उससे कहीं ज्यादा सरल है। क्योंकि फ़ाइल हैंडल फ़ाइल हैंडल के सभी डुप्लिकेट के लिए समान है ( setfilepositionइसके तर्क का उपयोग करता है, इसलिए यह उस फ़ंक्शन के लिए एकमात्र उपयोगी शब्दार्थ है)।

/LABELS 10 dict def 

/: { % n :  define label
    LABELS exch currentfile fileposition put 
} def 

/goto { % goto label
    currentfile exch LABELS exch get setfileposition
} def 

/x 0 def 

/here :
    /x x 1 add def 

    x 5 ne {
        /here goto
    } if

x =

यह प्रिंट करता है 5

उपरोक्त के साथ कुछ सीमाएँ हैं। कूद तत्काल नहीं है, लेकिन तब होता है जब आई-बॉडी शीर्ष-स्तर पर लौटती है और दुभाषिया फिर से फ़ाइल से पढ़ रहा है (इसके बजाय एरे से पढ़ने के लिए जिसमें इफ-बॉडी शामिल है)। उस बिंदु पर, फ़ाइल को फिर से भेज दिया गया है और 'गोटो' प्रभावी हो गया है।


और यह केवल एक शब्दकोश में परिभाषा है, इसलिए आप लेबल के लिए लगभग किसी भी प्रकार का उपयोग कर सकते हैं।
लूसर डॉग

आप फ़ाइल की शुरुआत से बाइट्स की गिनती के साथ पूर्ण छलांग भी लगा सकते हैं currentfile <pos> setfileposition
लूजर ने

4

Symbol#to_proc रूबी में तर्क के साथ

Symbol#to_procशायद सच में रूबी कोड लिखने के लिए मेरी पसंदीदा चाल में से एक है। मान लो तुम्हारे पास है

nums = [1, 2, 3, 4]
text = %w(this is a test)

और आप की सामग्री को परिवर्तित करना चाहते हैं numsऔर textतैरता और अपरकेस शब्दों को क्रमश। Symbol#to_procआपको इस तरह कोड को छोटा करने की अनुमति देता है:

nums.map { |num| num.to_f }
text.map { |word| word.upcase }

इसके लिए:

nums.map(&:to_f)
text.map(&:upcase)

बहुत बढ़िया! लेकिन क्या हम में प्रत्येक तत्व को बढ़ाने के लिए चाहते हैं, तो numsकरने के लिए iवें शक्ति, या के हर घटना की जगह sके साथ *में text? क्या इस तरह कोड को छोटा करने का कोई तरीका है?

nums.map { |num| num ** 1i }
nums.map { |word| word.gsub('s', '*') }

का उपयोग करते समय तर्क पास करने का कोई आसान तरीका नहीं है Symbol#to_proc। मैंने इसे कई तरीकों से देखा है, लेकिन शायद सबसे चतुर और प्रयोग करने योग्य दो में से एक है Symbol[ 1 , 2 ] कक्षा को बंदर-पैच करना । मैं नीचे पहला तरीका बताऊंगा।

class Symbol
  def with(*args, &block)
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
  end
end

अब आप निम्न कार्य कर सकते हैं:

nums.map(&:**.with(1i))
text.map(&:gsub.with('s', '*'))
nums.take_while(&:<.with(3))
text.delete_if(&:[].with('is'))

3

जावास्क्रिप्ट

var arr = ["Seattle", "WA", "New York", "NY", "Chicago", "IL"];

function foreach(fn, arr) {
  var s = fn.toString();
  var args = s.substring(s.indexOf('(')+1,s.indexOf(')')).split(",");
  var argsLen = args.length;
  var len = arr.length;
  for (var i = 0; i < len; i+=argsLen) {
    var part = arr.slice(i, i+argsLen);
    fn.apply(undefined, part);
  }
}

foreach (function(city, state) {
  console.log(city + ', ' + state);
}, arr);

उत्पादन

Seattle, WA
New York, NY
Chicago, IL

वैकल्पिक वाक्यविन्यास, Tcl की तरह।

// Tcl's foreach loop for javascript.
// Keys in loop are prefixed with "this".
function tclForeach(keys, values, fn) {
  var obj={}, klen=keys.length, vlen=values.length, j, i;
  for (i=0, klen=keys.length; i < klen; i++) obj[keys[i]]=null;
  for(i = 0; i < vlen; i+=klen) {
    for(j=klen; j--;) obj[keys[j]] = values[i+j];
    fn.apply(obj);
  }
}

tclForeach(["city","state"], arr, function() {
  console.log(this.city + ', ' + this.state);
});

यह एक सादा अग्र भाग नहीं है, लेकिन अधिक दिलचस्प है। यह खपत करने वाले फ़ंक्शन की तर्क सूची का निरीक्षण करता है। आप इस चाल के साथ आगे बढ़ सकते हैं और वास्तव में शांत चीजें कर सकते हैं।
जॉय एडम्स

1
मैं एक Tcl शैली के लिए जा रहा था। मैंने थोड़ा अलग दृष्टिकोण जोड़ा है जो Tcl की तरह अधिक है।
वोल्फहैमर

2

हास्केल में गोटोस

मूल विचार यह है कि गोटो को अंतिम विवरण में do-इनोटेशन का उपयोग करके आंशिक रूप से सिम्युलेटेड किया जा सकता है । उदाहरण के लिए:

main = do
  loop:
  print 3
  goto loop

के बराबर है

main = do
  loop
loop = do
  print 3
  loop

क्योंकि निष्पादन अंतिम विवरण के लिए कूद जाएगा, यह गोटो को व्यक्त करने के लिए इष्टतम है।

क्योंकि यह जिस तरह से किया जाता है, गोटो केवल कूदता है जब वे doसीधे एक टॉपवेल परिभाषा के ब्लॉक में होते हैं। यह वास्तव में "कॉल एक्स है और बाकी एक्सएक्सएक्स स्टेटमेंट्स को अनदेखा करें " बजाय सभी एक्स "और बाकी स्टेटमेंट्स को नजरअंदाज करें", असली गोटो की तरह।

सबसे बड़ी समस्या यह है कि जब एक IO कार्रवाई के बीच से निष्पादन को छोड़ने का कोई तरीका नहीं है - यहां तक returnकि नहीं; returnयह आखिरी बयान नहीं है जब कुछ भी नहीं करता है।

यह शेष कथनों को अन्य doब्लॉक द्वारा कैप्चर करके इसे समाप्त करता है ।

goto loop
print 3

हो जाता है

const loop $ do
print 3

print 3बयान से कब्जा कर लिया है doब्लॉक, इसलिए loopपिछले बयान हो जाता है।

यह परिवर्तन क्रियाओं के दायरे में मौजूद चर का भी समर्थन करता है। यह उन चरों को याद करके किया जाता है जो दायरे में हैं, और उन्हें क्रियाओं में पारित कर रहे हैं। उदाहरण के लिए:

printer r = do
  loop:
  putStrLn r
  goto loop
  print "this isn't executed"

यह बस में अनुवाद:

printer r = do
  loop r
loop = do
  putStrLn r
  const (loop r) $ do
  print "this isn't executed"

कुछ नोट:

return undefinedकैप्चरिंग doब्लॉक खाली नहीं है यह सुनिश्चित करने के लिए भी एक स्टेटमेंट जोड़ा जाता है।

क्योंकि कभी-कभी do, constहम उपयोग करने के बजाय कैप्चरिंग ब्लॉक में टाइप अस्पष्टता रखते हैं asTypeOf, जो समान है constलेकिन इसके दोनों मापदंडों को एक ही प्रकार की आवश्यकता होती है।

वास्तविक कार्यान्वयन (जावास्क्रिप्ट में):

function makeGoto(code)
{
    var vars = [] // the known variables

    // add the arguments to the functions to scope
    code.split('\n')[0].split('=')[0].split(' ').slice(1).forEach(function(varname){vars.push(varname)})
    return code.replace(/([ \t]*)([a-zA-Z]+):|([ \t]*)goto[ \t]+([a-zA-Z]+)|[ \t]+([a-zA-Z]+)[ \t]*<-/gm, function match(match, labelSpaces, label, gotoSpaces, goto, x)
        {
            if (label != undefined)
                return labelSpaces+label+" "+vars.join(' ')+"\n"+label+" "+vars.join(' ')+"=do ";
            else if(goto != undefined)
                return gotoSpaces+"asTypeOf("+goto+" "+vars.join(' ')+")$do\n"+gotoSpaces+"return undefined";
            else
            {
                vars.push(x);
                return match
            }
        })
}

एक परीक्षा:

main = do
    putSrtLn "a"
    goto label
    putStrLn "b"
    label:
    putStrLn "c"

हो जाता है:

main = do
    putStrLn "a"
    asTypeOf(label )$do
    return undefined
    putStrLn "b"
    label 
label =do 
    putStrLn "c"

उत्पादन:

a
c

यह स्पष्ट करने योग्य है कि returnहास्केल एक नियमित कार्य है, और C / etc में कीवर्ड से असंबंधित है।
फायरफ्लाइ

1

पायथन गोटो

goto.py

import sys, re
globals_ = globals()
def setglobals(g):
    global globals_
    globals_ = g
def goto(l):
    global globals_ 
    with open(sys.argv[0], "rb") as f:    
        data = f.read()
        data_ = data.split('\n')
    if isinstance(l, int):
        l-=1 if l > 0 else 0
    elif isinstance(l, str):
        r=re.search(r"^\s*(#{0}|(def|class)\s+{0})".format(l), data, re.MULTILINE)
        l=len(data_)-(data[r.start():].count("\n")) if r else len(data_)
    if 0 < l < len(data_) or 0 < (l*-1) <= len(data_):
        exec("".join(data_[l:]),globals_)
        sys.exit(1)

प्रयोग

setglobals(globals()) #Set the globals to be used in exec to this file's globals (if imports or other variables are needed)
goto(8) #Goto line 8
goto(-8)#Goto 8th last line
goto("label")#Goto first occurrence of #label
goto("funcName")#Goto definition of funcName
goto("className")#Goto definition of className

सैंपल टेस्ट केस

import goto, sys
goto.goto(-1)
sys.exit(-1)

print "Asdf"

सैंपल टेस्ट केस आउटपुट

Asdf

निष्पादन के साथ बस थोड़ा सा मज़ा ()। यदि ठीक से उपयोग नहीं किया जाता है तो अधिकतम पुनरावृत्ति गहराई त्रुटि उठा सकते हैं।


-2

// आयात जावास्क्रिप्ट को बिना HTML टैग में स्क्रिप्ट टैग का उपयोग करते हुए

function i(u) {
  document.write("script src=\" + u + \"></script>");
}

i("http://www.mysite.com/myscript.js");

यह लंगड़ा है हाँ मुझे पता है। लंबाई: 99


@ user2509848: यह धागा कोड गोल्फ टैग नहीं है।
जोए एडम्स

आपने जो पोस्ट किया है, scriptउसके चारों ओर टैग की आवश्यकता है। फिर नई सुविधा कहाँ है?
मैनेटवर्क

@JoeyAdams ओह, माफ करना।
१२:१२ पर होशो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.