digitalmars.D.announce - Til, a command language written in D
- =?UTF-8?B?Q2zDqWJlcg==?= Zavadniak (45/45) May 14 2021 Hey, folks, how you doing?
- Witold Baryluk (11/18) May 14 2021 Nice. Pretty clean syntax, and the implementation.
- =?UTF-8?B?Q2zDqWJlcg==?= Zavadniak (38/48) May 14 2021 Thanks! I'm relatively new to D itself, I'll confess. Suggestions
- kinke (7/9) May 18 2021 With LDC, -link-defaultlib-shared links the binary against shared
- =?UTF-8?B?Q2zDqWJlcg==?= Zavadniak (26/35) Jun 05 2021 Tried that for both a shared library (libtil_exec.so) and the
- =?UTF-8?B?Q2zDqWJlcg==?= Zavadniak (21/21) Jun 05 2021 Heeey! Fixed it! Thanks to this 2016 thread:
Hey, folks, how you doing? 2 months ago I started playing with a small personal project: creating a simple programming language / interpreter, both for fun and for learning more about... you know... creating a programming language / interpreter. :-) Now, *I'm not exactly a Walter Bright*, so I decided to start with a **dynamic, Tcl-like language: command-based and without much "syntax"**. I tried to avoid the "*everything is a string*" concept and even played for some time with "*everything is a list*" (almost like Lisp, but with fewer parentheses) and even "*everything is a forward range*" - the results, then, were **horrible**, but, anyways... I've learned interesting lessons (specially: how important, powerful and versatile a simple STACK is). [Til](https://github.com/til-lang/) is now mature enough, IMHO, to the point I'm spending more time writing documentation and "spreading the word" than coding that much. I published two packages on Dub (the language itself and a module) and created a [Github-Pages-Website](https://til-lang.github.io/til/), already. I'm not pretentious in any form (I know it's just "*yet another language*"), but I'm actually very happy with the results: I can write programs in a interpreted language (I appreciate the power and development speed it gives me) and can extend it with another very nice (and powerful) language - D. (Most other languages still follow the formula "extend it with C" and, although I consider myself a "C friendly" guy, that usually doesn't appeal that much to me..) Anyway: the last thing I was working was **loading dynamic libraries as "modules"** and I stumbled across the potential problem of having two different GCs running independently. This article, https://dlang.org/articles/dll-linux.html , talks about linking the results (both the interpreter and the shared library) with `libphobos2.so` -- but it's nowhere to be found on my (Void) Linux system (and neither on FreeBSD). So I have some questions: 1- Should I compile a `libphobos2.so` "by hand"? Should I use `libphobos2-ldc-shared.so`??? 2- Is the GC really going to run on my shared library after loading it? (I think that's maybe a "silly question", but also believe it's worth clarifying the matter.) I appreciate any help. (Furthermore, I'd like to thank to all people helping to make D a language (and ecosystem and community) even more amazing each day. :-) (FurtherEvenMore: I'm new to the forum, so I hope I choose the right place to post this message...)
May 14 2021
On Friday, 14 May 2021 at 22:10:38 UTC, Cléber Zavadniak wrote:Hey, folks, how you doing?Good. Hope you are doing good too.[Til](https://github.com/til-lang/) is now mature enough, IMHO, to the point I'm spending more time writing documentation and "spreading the word" than coding that much. I published two packages on Dub (the language itself and a module) and created a [Github-Pages-Website](https://til-lang.github.io/til/), already.Nice. Pretty clean syntax, and the implementation. I am not a fan of Tcl, but the Erlang influences are definitively cool. I like sub processes and the piping. Do you have some example of running external processes / commands. with `Til`? Composing pipes between external processes, and also between internal ones (maybe by some adapter that splits pipe data by lines?). A good alternative to bash is always welcome ;D
May 14 2021
On Friday, 14 May 2021 at 22:18:50 UTC, Witold Baryluk wrote:Nice. Pretty clean syntax, and the implementation.Thanks! I'm relatively new to D itself, I'll confess. Suggestions of improvements to the code are welcomed.I am not a fan of Tcl, but the Erlang influences are definitively cool.I myself find Tcl awesome. But it has a lot of flaws, too. I'm kind of trying to fix some of its issues, as well (the first versions of Til were labeled "a better Tcl"). (Also: a Tcl-based has the advantage that I can use its syntax highlighting satisfactorily on most of the cases.)I like sub processes and the piping. Do you have some example of running external processes / commands. with `Til`? Composing pipes between external processes, and also between internal ones (maybe by some adapter that splits pipe data by lines?).The module I published on Dub is [til_exec](https://code.dlang.org/packages/til_exec) and it runs commands and returns status and output, for now. (I'm trying to avoid the "giant standard library included" path, so I prefer to release modules separately.) There's a lot of things lacking right now, for sure: you can `exec` commands but there's no way, yet (future readers: please pay attention to the timestamp of this post. Thanks), of breaking the command output in multiple lines. (An example I can think would be the following, but `string.split` is the lacking part, currently:) ```tcl exec ls / | string.split "\n" | foreach line { io.out $line } ``` Interestingly, Til *pipes* were not born actually focused on handling external commands I/O, unix-shell-style, despite the obvious similarity. The first pipes implementation was an attempt to avoid Tcl sometimes-weird nested-commands syntax (used a lot for indexing) for instance, like `set parts [file split [file rootname $file_path]]`. But it evolved to be a way of handling **data** in general, while function parameters were supposed to define mostly **behavior**.A good alternative to bash is always welcome ;DYeah... I don't know... Not following this goal right now. `bash` is still out there for some very good reasons, as far as I can see. Some things are just expected in a shell, like expanding `*`, and usually general-purpose programming languages just feel weird handling "shell things". (But... who knows?...)
May 14 2021
On Friday, 14 May 2021 at 22:10:38 UTC, Cléber Zavadniak wrote:1- Should I compile a `libphobos2.so` "by hand"? Should I use `libphobos2-ldc-shared.so`???With LDC, -link-defaultlib-shared links the binary against shared druntime/Phobos. It's the default setting when creating a shared library with -shared; use it explicitly when creating an executable. This way, the executable and all .so libs share the same druntime/Phobos, incl. a single GC, default std.parallelism thread pool etc.
May 18 2021
On Tuesday, 18 May 2021 at 15:19:50 UTC, kinke wrote:On Friday, 14 May 2021 at 22:10:38 UTC, Cléber Zavadniak wrote:Tried that for both a shared library (libtil_exec.so) and the interpreter itself but with LDC2 it keeps throwing this: object.Exception source/til/modules.d(100): dlsym error: Library ../til/til.debug is not already loaded "../til/til.debug" is the interpreter executable. The intepreter try to load the name "getCommands" from the shared library with: auto getCommands = cast(CommandHandlerMap function(Process))dlsym( lh, "getCommands" ); (https://github.com/til-lang/til/blob/8213ab61b87a478f9b2d140a370a870dc9bb0fc9/source/til/modules.d#L94) Using DMD, everything goes smooth... `objdump -T libtil_exec.so` shows the name is there as it should in the shared library: 000000000006df40 g DF .text 0000000000000069 getCommands LDC2 info: $ ldc2 --version LDC - the LLVM D compiler (1.26.0): based on DMD v2.096.1 and LLVM 12.0.0 built with DMD64 D Compiler v2.095.0 Default target: x86_64-unknown-linux-musl Host CPU: skylake Trying to figure out what's happening, here, but any help is welcome...1- Should I compile a `libphobos2.so` "by hand"? Should I use `libphobos2-ldc-shared.so`???With LDC, -link-defaultlib-shared links the binary against shared druntime/Phobos. It's the default setting when creating a shared library with -shared; use it explicitly when creating an executable. This way, the executable and all .so libs share the same druntime/Phobos, incl. a single GC, default std.parallelism thread pool etc.
Jun 05 2021
Heeey! Fixed it! Thanks to this 2016 thread: https://forum.dlang.org/post/o3tvfh$1lvk$1 digitalmars.com In short: 1. call `dlerror()` to clean up any eventual old error messages (just in case); 2. do **not** look into `lh` (the "library handler") to check for errors, because it **can** be null even without any error (see Jacob Carlborg answer on that thread) 3. after calling `dlopen`, using the result of another call to `dlerror()` to check for errors (it should be NULL if everything went okay). Yay! Now I can create modules linked against `libphobos2` shared library! ldd libtil_exec.so ldd (0x7f8ccd0d9000) libphobos2-ldc-shared.so.96 => /usr/lib/libphobos2-ldc-shared.so.96 (0x7f8cccb6b000) libdruntime-ldc-shared.so.96 => /usr/lib/libdruntime-ldc-shared.so.96 (0x7f8ccca0e000) libunwind.so.1 => /usr/lib/libunwind.so.1 (0x7f8ccc9f7000) libc.so => ldd (0x7f8ccd0d9000)
Jun 05 2021