Hacker News new | ask | show | jobs
by kazinator 4061 days ago
You might as well use the POSIX shell to write your code:

   cat <<END
   $(for x in A B C; do
       echo "proc $x() = echo \"$x\"";
     done)
   
   proc execute(order: seq[int], callbacks: seq[proc]) =  
     for i in items(order):                              
       callbacks[i]()

   execute(@[0,0,1,2,1,2], @[A, B, C])
   END
2 comments

It's great that both Nim and Bash are so easy to read and write. The beauty of Nim is it makes writing performant C code as easy as writing Python.
It worked!

Now how do I incorporate this into my tool chain (Makefile)?

Believe it or not, I actually did this years ago, and I have the Makefile somewhere. [... search ...] Found the rules!

  %: %.ct
        cpp -P $(shell env | sed -e "s/.*/-D_ENV_'&'/") $< > $@

  %: %.st
        ( export __FILE__=$< ; echo "cat <<!" ; cat $< ; echo "!" ) | bash > $@

  %: %.mt
        rm -f $@.err
        m4 -D__FILE__=$< $(shell env | sed -e "s/\([^=]*\)=\(.*\)/-D'_ENV_\\1=\\2'/") $< > $@
        if [ -s $@.err ] ; then cat $@.err ; exit 1 ; fi
        rm -f $@.err
Explanation: this gives you three "flavors" of preprocessing. ".ct" files are "C preprocessor templates"; they are put through cpp. ".mt" files are M4 templates: M4 is used. And ".st" are shell templates; they use shell here-doc syntax.

The shell templates do not have to have any "cat <<" or "!"; this wrapping is added by the Makefile. Of course, you can't have a line consisting of ! in these files; you have to escape such a thing if it occurs.

Additionally, for .ct and .mt files, all environment variables are turned into macros in that language, with their names mapped to the the _ENV_* namespace. For .st and .mt files, the __FILE__ macro is established which expands to the file name (the C preprocessor has this built-in).

I used this in an embedded Linux distro that I build from scratch (targetting MIPS embedded hardware). It was used for generating some of the textual materials in the target file system tree. For instance /etc/hosts was generated from a .st template, and populated using a $(for ...) loop.

Yes, I do Lisp and I do stupid. :)

Nice!

> Yes, I do Lisp and I do stupid. :)

Why stupid? I think that is straight solutions for simple problems. MyDef is basically the same idea but with complete programming layer to achieve almost anything. I have been using MyDef for all my programming (in all programming languages) for 10 years now, solves all my syntax problems. It doesn't solve language problems therefore I still choose language to suite problems. However it turns out that programming language minus syntax features are much smaller and the remaining criterion often boils down to library availability, dynamic type vs static, or memory management. Syntax differences can be naturally dismissed.

Looks like your MyDef is bootstrapped using itself; it seems to be written in "MyDefized" perl.

Bravo; it is much more readable than regular Perl.

Thanks.

MyDef is not really a programming language, but a meta layer. Sounds like a new concept but it is more like cpp or m4 in the toolchain point of view. As such, it can work with any programming languages. e.g. In the Nim example, every thing written is Nim, except the macro; and MyDef itself is actually in 100% Perl (the bootstrap folder is actually a pure Perl package). However, specific extension/plugin also can be written for specific language to customize and gain special power; I did that for Perl and C.