Live data from Hacker News

Carp: a statically typed lisp, without a GC, for high performance applications

github.com

61–70 of 71 posts

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#61
post #24

Looks like just what I have been trying to find, since I am incapable of writing my own. I did start with 'Learn C * Build Your Own Lisp' book [1], and I will finish it for educational purposes; it is a great, short book to work through, and should help with grokking Carp. The closest I have come to finding something similar for livecoding visuals and audio, or games is Extempore [2], which has xtlang, a Scheme, with…

You should have a look at Hypergiant library for Chicken Scheme. It compiles to C as well. https://github.com/AlexCharlton/Hypergiant

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#62

I saw this a month or two ago and submitted a pull request that I still need to fix up to have it accepted. My original intention was to benchmark a bit against SBCL, but I got sidetracked with the pull request, then lost time and then forgot about it. I need to get back to it and see about getting it submitted. Anyway, it sounds neat, but even after playing with it a bit, I'm not sure how necessary it is. SBCL (and…

I believe one major motivation behind Carp is the lack garbage collection. Or rather, avoiding GC pauses. So, maybe you could benchmark Carp vs SBCL in that area?

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#63
post #55

Earlier quoted context omitted.

Very simple. Each C allocated structure is allocated at the end of its C scope, and free'd at each end. Since the compiler knows the scope of each variable it's trivial. Harder is of course the ffi, which doesn't generally know if the extern call allocated something. This is undecidable for the compiler and he has to trust the user/program. Other lisps have an attribute for those externally malloc'd args.

No, really no. First of all the values of the variables can escape their scope, e.g. when used as a return value. Secondly, some child scopes outlive their parents, e.g. closures. As the parent comment correctly points out you'd literally need to solve the halting problem to infer all the lifetimes for arbitrary code.

tracking the scope of vars is a simple compiler job (yes, also across functions, when used as byval or byref args or return values) and not a uncomputable problem. please stop spreading fud.

you only need a GC to recycle cyclic data structures, with links back to previous nodes. since Carp does not create such data structures in the generated C code the reclamation scheme can be kept simple.

heap vars to be kept global (such as closed-over upvals you are complaining about to be leaking) are kept global and released at the end. every dynamic language does keep it functions and closed over values global.

however, lexical closures are released at the end of scope, and remaining tracked heap vars are copied.

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#64
post #57
post #19

This is fantastic. AFAIK there are no Lisps our there that are designed with games in mind which is a huge shame because I often think how perfect it'd be for game dev (Arcadia and Nightmod spring to mind but imo they're shoehorns. Good ones, but still).

There are a couple of high-performance, low-latency lisps, either with a low-latency GC or refcounted or compiling to C as Carp does. ECL (also typed), Vicare, Larceny, Ypsilon, the new guile, Gambit-C, Chicken, Chez, Bigloo, stalin, Corman CL, or fast typed CL: sbcl, franz, lispworks and few more. Or the ones compiling to LLVM or JVM or .NET. Most prominent Clojure with a very unlispy syntax.

And note that you simply get a low-latency GC with libgc (Boehm-Weiser) by using the incremental GC with GC_enable_incremental() and SMP with parallel marking phases -DPARALLEL_MARK. http://www.hboehm.info/gc/scale.html This is no voodoo nobody ever managed to do, even if most blog posts for popular not-invented-here languages state the opposite.

Of course libgc is pretty simple and slow, good for foreign code (i.e. ffi's needed in games), slower than Cheney-2 finger copying allocators which I got down to 10ms, compared to 100-300ms for mark-sweep. But copying collectors need 2x memory, so not usable for small devices such as phones. And a bit complicated for foreign memory, which prefers conservative mark & sweep.

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#65
post #61
post #24

Looks like just what I have been trying to find, since I am incapable of writing my own. I did start with 'Learn C * Build Your Own Lisp' book [1], and I will finish it for educational purposes; it is a great, short book to work through, and should help with grokking Carp. The closest I have come to finding something similar for livecoding visuals and audio, or games is Extempore [2], which has xtlang, a Scheme, with…

You should have a look at Hypergiant library for Chicken Scheme. It compiles to C as well. https://github.com/AlexCharlton/Hypergiant

I did. I'll have to revisit it. I gave it up, since I work on Windows and Linux mainly, and I think I couldn't get one or more of the dependencies working on Windows, and I gave up. I really like Chicken, but with Chez Scheme having gone opensource, I use it now when I am working in a Scheme.

I've also looked at Lobster, which is now statically typed by default, not optional.

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#66
post #63

Earlier quoted context omitted.

No, really no. First of all the values of the variables can escape their scope, e.g. when used as a return value. Secondly, some child scopes outlive their parents, e.g. closures. As the parent comment correctly points out you'd literally need to solve the halting problem to infer all the lifetimes for arbitrary code.

tracking the scope of vars is a simple compiler job (yes, also across functions, when used as byval or byref args or return values) and not a uncomputable problem. please stop spreading fud. you only need a GC to recycle cyclic data structures, with links back to previous nodes. since Carp does not create such data structures in the generated C code the reclamation scheme can be kept simple. heap vars to be kept glob…

> heap vars to be kept global (such as closed-over upvals you are complaining about to be leaking) are kept global and released at the end.

In other words, they leak if the program no longer references them.

> every dynamic language does keep it functions and closed over values global.

Yes, but most of them collect closed-over values when they are no longer used. Using a garbage collector. To avoid memory leaks.

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#67
post #63

Earlier quoted context omitted.

tracking the scope of vars is a simple compiler job (yes, also across functions, when used as byval or byref args or return values) and not a uncomputable problem. please stop spreading fud. you only need a GC to recycle cyclic data structures, with links back to previous nodes. since Carp does not create such data structures in the generated C code the reclamation scheme can be kept simple. heap vars to be kept glob…

> heap vars to be kept global (such as closed-over upvals you are complaining about to be leaking) are kept global and released at the end. In other words, they leak if the program no longer references them. > every dynamic language does keep it functions and closed over values global. Yes, but most of them collect closed-over values when they are no longer used. Using a garbage collector. To avoid memory leaks.

Oh my, have you ever implemented a dynamic language?

Tracked global vars are of course free'd at the end of the program. There's no leak.

2nd closed-over values inside global closures can only be freed at end. A common problem in non-GC'd languages, which can only be fixed by adding a GC. Yes. The goal here is to avoid a GC. So don't reference big memory inside closures (as upval or return val, local is OK), or undef them explicitly, as in every dynamic language.

Using local closures would fix that, but Carp has no syntax for that I think. It would need an assignment from lambdas. Most langs prefer a simple global deffun variant instead. Lua got that right. That's why lua is the preferred game VM. But being able to use the easier and more simple lisp syntax should be preferred.

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#68
post #11

To the author: please, please, please port (or reuse) LuaJIT's C-header parser for FFI; it's the best FFI interface specification method if seen among JNI, Python, V8 and even C# (because you can just use the C header, with support for typedefs, unions and packing). It really looks like a great language!

Interesting, thanks a lot for the tip!

Also check out Pixie's - towards the end of https://www.youtube.com/watch?v=1AjhFZVfB9c. It's a really interesting technique, and for a Lisp too.

Re: Carp: a statically typed lisp, without a GC, for high performance applications

#69
post #67

Earlier quoted context omitted.

> heap vars to be kept global (such as closed-over upvals you are complaining about to be leaking) are kept global and released at the end. In other words, they leak if the program no longer references them. > every dynamic language does keep it functions and closed over values global. Yes, but most of them collect closed-over values when they are no longer used. Using a garbage collector. To avoid memory leaks.

Oh my, have you ever implemented a dynamic language? Tracked global vars are of course free'd at the end of the program. There's no leak. 2nd closed-over values inside global closures can only be freed at end. A common problem in non-GC'd languages, which can only be fixed by adding a GC. Yes. The goal here is to avoid a GC. So don't reference big memory inside closures (as upval or return val, local is OK), or undef…

> problem [...] which can only be fixed by adding a GC

Cool, we're agreed then.

Post reply on HN