Live data from Hacker News

Show HN: Lisp in C#

github.com

51–60 of 70 posts

Re: Show HN: Lisp in C#

#51
post #47

Earlier quoted context omitted.

Given how easy it is to expose functionality from the host language using existing facilities [0], and how complicated a reflection based FFI could get; I would rather not, at least not right now. It's also one of those decisions that will drastically limit my choices for future evolution of the implementation. The general idea is to use both languages together, as complements; not calling one from the other. https:/…

Ah, this is actually what I had in mind by "interop". So from C# I can evaluate some Lisp code and then test that the result is `PairType` (for example)? Maybe this is so obvious it goes without saying, but I didn't see any examples of that.

I understand.

Sure thing, VM.Eval("your code") returns a value if one is produced.

  if (vm.Eval("1:2") is Value v and v.Type == Libs.Core.Pair) {
    Console.WriteLine("Pair: " + v.Cast(Libs.Core.Pair));
  }
Have a look in the main Program.cs to see how to get a VM up and running.

Re: Show HN: Lisp in C#

#52
post #40

Earlier quoted context omitted.

> As description in PR indicates, it’s just a default catch-all gitignore that you can add with ‘dotnet new gitignore’ that covers all kinds of tools and build artifacts, I see no reason to customize it. Ah, someone should just come up with a huge file so we can ignore every possible combination at this point :) > like JS ecosystem Heh, JS is probably the language that generates the least trash by default as it's jus…

GitHub doesn't have it all in one huge file, but has a somewhat comprehensive template repo of many ecosystems: https://github.com/github/gitignore (This is what is used to populate the templates if you ask GitHub to include a gitignore when creating a new repo, or if you add a new file to a Repo and name it .gitignore and get the template selector to show up.) I believe `dotnet new gitignore` basically shares the sa…

Just seem a bit backwards to start with a gitignore that ignores every possible tool one could use with a particular language, rather than going directory/file/pattern by directory/file/pattern. Hence my proposal for these people to take the contents of the github/gitignore repository, fold it all into one big file they can reuse in all their repos, and call it a day.

Like why is there a `.DS_Store` (which is specific to macOS) in the `core.gitignore` file? That belongs in the global `.gitignore` macOS users should have in their home directory, rather than including it in project specific .gitignore.

But I digress, not exactly a huge problem and I won't lose any sleep over it :)

Re: Show HN: Lisp in C#

#53
post #38
post #28

Earlier quoted context omitted.

Observant :) Polyglot projects have been sort of a thing lately, because micro services made them doable I guess; but I feel the combination of a capable and portable host language and a scripting language implemented in that language captures the best of both worlds while adding nice super powers on top.

You mean rebranding distributed computing and OS IPC for newer generations?

It's the same old ideas, over and over again.

But it's not a circle, it's a spiral; we learn something new every time.

Re: Show HN: Lisp in C#

#54
post #30

Separate from anything else, I'm ... concerned ... at the idea of ints being iterable, because it seems like something I'd be much more likely to invoke accidentally than intentionally and then wonder wtf my program was doing. I'd prefer to have to write something like (reduce + (range 1 3) 0) and if you find yourself wanting the natural number iteration regularly maybe (^upto (n) (range 1 (- n 1))) as sugar. This co…

Integers are also iterable in TXR Lisp. But in a different way; you get an infinite sequence starting from the value. 1> [mapcar list '(a b c) 10] ((a 10) (b 11) (c 12)) This crops up on a regular basis in my coding, removing verbosity; I don't regret the decision. It's one of the "take alongs": something to repeat in a future language.

The duality of meaning (is it from or to the specified value) actually speaks against the feature for me, you just ruined it :)

Or fixed it, depending on which way you lean.

Re: Show HN: Lisp in C#

#55
post #52

Earlier quoted context omitted.

GitHub doesn't have it all in one huge file, but has a somewhat comprehensive template repo of many ecosystems: https://github.com/github/gitignore (This is what is used to populate the templates if you ask GitHub to include a gitignore when creating a new repo, or if you add a new file to a Repo and name it .gitignore and get the template selector to show up.) I believe `dotnet new gitignore` basically shares the sa…

Just seem a bit backwards to start with a gitignore that ignores every possible tool one could use with a particular language, rather than going directory/file/pattern by directory/file/pattern. Hence my proposal for these people to take the contents of the github/gitignore repository, fold it all into one big file they can reuse in all their repos, and call it a day. Like why is there a `.DS_Store` (which is specifi…

One of the problems in having a single gitignore to ignore all the possible things that there's no strict superset without overlaps. Visual Studio uses files called .user that contain user-specific metadata that should never be committed to source control and other systems might use .user for components that should be committed to source control. Breaking it down by language ecosystem seems an adequate compromise as few repos use multiple languages and when they do there's often a folder hierarchy to respect with nested gitignores.

Re: Show HN: Lisp in C#

#56
post #19
post #8

years ago someone posted http://norvig.com/lispy.html here on HN I wrote a lisp in C# based on that, it was only a 100+ ish lines of code. It was a great way to get into Lisp.

Yes, I am aware. I started out designing Forth interpreters, actually calculators and template engines, but Forth was a natural progression. My design differs a lot from idiomatic Lisp implementations (likewise Forth), and I do sometimes wonder what it would look like if you started in that end and worked your way towards supporting all the features of sharpl.

Having thought a bit about it, one motivation for choosing the route I did; rather than the more idiomatic one; is that it relies on pipeline of source transformations to get to optimal code.

The initial expansion is often pretty sloppy.

I don't do many source transformations, everything is designed to emit pretty optimal byte code on the first pass.

Re: Show HN: Lisp in C#

#57
post #54

Earlier quoted context omitted.

Integers are also iterable in TXR Lisp. But in a different way; you get an infinite sequence starting from the value. 1> [mapcar list '(a b c) 10] ((a 10) (b 11) (c 12)) This crops up on a regular basis in my coding, removing verbosity; I don't regret the decision. It's one of the "take alongs": something to repeat in a future language.

The duality of meaning (is it from or to the specified value) actually speaks against the feature for me, you just ruined it :) Or fixed it, depending on which way you lean.

It would not be often useful to have it count up from 1 or zero up to or below the value; I would not have designed it that way. In many situations you don't know the upper limit of what is enumerated; it comes implicitly from the lengths of other sequences or in other ways.

It's also less inefficient, because the value has to be converted to an iterator object that knows about the range, and keeps track of the state.

In TXR Lisp, certain objects are self-iterable, like characters, numbers and good old conses.

  1> (iter-begin "abc")
  #
  2> (iter-begin 3)
  3
  3> (iter-begin '(a b c))  
  (a b c)
To iterate a string, we need to obtain a seq-iter object, but for 3 and (a b c), we do not. With these objects, we have all the state we need in order to iterate.

  4> (iter-more 3)
  t
  5> (iter-item 3)
  3
  6> (iter-step 3)
  4
  7> (iter-more '(a b c))
  t
  8> (iter-item '(a b c))
  a
  9> (iter-step '(a b c))
  (b c)
  10> (iter-more *1)
  t
  11> (iter-item *1)
  #\a
  12> (iter-step *1)
  #
  13> (iter-item *1)
  #\b
iter-step may or may not destructively update its argument, so you always have to capture the return value and forget about the original.

You can see how for a list, iter-more is equivalent to (not (null ...)), iter-item is just car, and iter-step is just cdr.

There is also lazy processing in TXR Lisp. E.g. lazy mapcar which is mapcar*. The following will only read the first few lines of the syslog, returning instantly:

  14> (take 3 [mapcar* cons 1 (file-get-lines "/var/log/syslog")])
  ((1 . "Jul 23 00:09:54 sun-go systemd[1]: openvpn@client.service: Service hold-off time over, scheduling restart.")
   (2 . "Jul 23 00:09:54 sun-go systemd[1]: openvpn@client.service: Scheduled restart job, restart counter is at 1044619.")
   (3 . "Jul 23 00:09:54 sun-go systemd[1]: Stopped OpenVPN connection to client."))

Re: Show HN: Lisp in C#

#58
post #53
post #38

Earlier quoted context omitted.

You mean rebranding distributed computing and OS IPC for newer generations?

It's the same old ideas, over and over again. But it's not a circle, it's a spiral; we learn something new every time.

Sometimes, and suddenly modular monoliths become a thing, as the microservices generation learns why we weren't doing SUN RPC, TOOL, DCOM and CORBA for every little piece of application functionality.

Re: Show HN: Lisp in C#

#59
post #5

Author here. I'm afraid I've been out of the C# loop too long to know what's fast and what isn't these days. Now that maybe I have the attention of some serious C# nerds, any assistance in making this thing run faster would be much appreciated. It's not terrible atm, given a managed host language, but I'm sure there are plenty of knobs left to turn. See the benchmarks section in the README for more info, and the same…

I haven't had chance to look over the code but I know that using Span for parsing might be a nice thing to try out. Have you considered making it compile to IL? Or if not that, using the Roslyn API to compile it to C# which is then automatically faster as a result of being compiled. Then getting AOT (ahead-of-time compilation) at build time gives you improved perf basically for free. I see neon has contributed a perf…

For small short-lived scripts the compilation (in any native form) time may be much bigger than bytecode execution time. And if a platform does not support dynamic code generation the end result is non-functional code or interpreter inside interpreter for LINQ expressions (as they can still run as interpreted, at least they try). See a comment in Jint readme about that.

I tried to compare some script languages implemented in C# with Roslyn script compilation. Same code to sum up 1M doubles. Roslyn takes almost 100ms to compile the code.

This may become especially painful when source code changes on every execution and reusing compilation result is not possible for some reason, e.g. user input or parametrized string template.

Re: Show HN: Lisp in C#

#60
post #54

Earlier quoted context omitted.

The duality of meaning (is it from or to the specified value) actually speaks against the feature for me, you just ruined it :) Or fixed it, depending on which way you lean.

It would not be often useful to have it count up from 1 or zero up to or below the value; I would not have designed it that way. In many situations you don't know the upper limit of what is enumerated; it comes implicitly from the lengths of other sequences or in other ways. It's also less inefficient, because the value has to be converted to an iterator object that knows about the range, and keeps track of the state…

Counting from 0 up to a value is the standard for loop, or numbering things (possibly with using the value with an offset).

But like I said, I'm not so sure there is a right way to interpret it any more.

Post reply on HN