Live data from Hacker News

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

github.com

51–60 of 71 posts

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

#51
post #6

Earlier quoted context omitted.

It is homoiconic, because the data structures used to describe code are also data structure provided by the language. However, brackets mean that you pass arguments as arrays instead of lists: there is little reason except aesthetics to have this distinction in source code. I prefer parenthesis everywhere, but some people really dislike that.

Yes, it's still homoiconic. I think vectors for argument lists is mainly a usability affordance. Which gives you aesthetics for free. (If you happen to find it more aesthetic.) > Common LISP and Scheme are not simple in this sense, in their use of parens because the use of parentheses in those languages is overloaded. Parens wrap calls. They wrap grouping. They wrap data structures. And that overloading is a form of…

I found that definition, applied liberally, lost its effectiveness.

I've never found the use of parenthesis to be an inhibiting factor in the complexity of Lisp code. It's a piece of syntax that has a single use and isn't ever over-loaded. A parameter list... is a list. A form... is a list with a specific structure. Surprise. The hyper-spec is very clear on this (i.e.: there is no over-loading).

I don't think his justification for [] was really necessary. If you want a different syntax for the defun macro you're free to have at it in Lisp. Clojure did nothing special there. Most schemes could interchange braces if you wanted to. You could easily write your own defn macro with your preferred syntax. It is no great innovation to use a different syntax so I don't know why he bothered making that remark about Lisp.

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

#52
post #47
post #44

Earlier quoted context omitted.

So it rejects code for which it can't prove lifetimes. Why not just say so? There's an uncomfortable degree of beating around the bush in this thread.

Curious if semantics of this subdomain of "allowed/legal" programs will be easy to understand, or will it be "try and see on case-by-case basis if your code compiles". Still, this way or the other, probably user will have to gradually learn and build intuition, as with learning any other aspect of any programming language. Also: will be/is the lifetime-checking done in the same way in the interpreter, even though it…

It will require roughly the same amount of practice as when learning Rust, so a pretty significant learning effort I'm afraid.

I'll try to do as much checking as possible in the interpreter so that the transition from interpreted to compiled code is smooth. Right now there is none though.

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

#53

Earlier quoted context omitted.

No tail recursion at the moment but it's something I'd be interested in adding later. I'm being very conservative with adding different type constructs but sure, Rust & Go certainly gets a lot of things right in that department and I'll consider their solutions for the future development of Carp.

Neat to see a contender to replace what should've had plenty of adoption in this area: https://en.wikipedia.org/wiki/PreScheme I still don't see a clear answer to junkie's question despite a huge thread. Let's be specific: "Where no GC is used, how exactly do you handle the issue of memory safety? Is it no safety like C, a specific analysis like Rust, or something different entirely?" Far as concurrency, you probably…

Thanks for the links!

The short answer is that safety is handled similar to Rust, using lifetime analysis. It's quite a bit more simplistic than Rust at the moment though. Also, some checks are done at runtime (like bounds checking on arrays, when turned on).

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

#54
post #37

Earlier quoted context omitted.

1. Yes, and yes! 2. No plans for inheritance at the moment, probably some kind of interfaces but that's not a top priority right now. Custom types are limited to structs, I will add union types soon 3. This has not been decided yet, I want to do more research before settling on any particular solution. It will be a high priority though, since I want to use it for the games I write Thanks, Erik

Is the plan for this to be a stand-alone gaming language or a language for embedding into a gaming engine or framework like Lua? Obviously built-in threading constructs are less essential for the latter.

Primarily stand-alone.

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

#55
post #40
post #33

Earlier quoted context omitted.

Very simple. The compiler, written in lisp (with a GC) just generates C code, which is compiled and executed. Without any GC, it tracks the vars.

No, not simple. Analyzing an arbitrary lisp program to determine the lifetimes of all allocated structures reduces to the halting problem, so it's undecidable. You must either restrict the input program or tolerate some leaks.

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.

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

#56

Earlier quoted context omitted.

Neat to see a contender to replace what should've had plenty of adoption in this area: https://en.wikipedia.org/wiki/PreScheme I still don't see a clear answer to junkie's question despite a huge thread. Let's be specific: "Where no GC is used, how exactly do you handle the issue of memory safety? Is it no safety like C, a specific analysis like Rust, or something different entirely?" Far as concurrency, you probably…

Thanks for the links! The short answer is that safety is handled similar to Rust, using lifetime analysis. It's quite a bit more simplistic than Rust at the moment though. Also, some checks are done at runtime (like bounds checking on arrays, when turned on).

Using the information on dependent types and some inference and eliminate run-time type checks in those cases would be a nice type-checker job, e.g. for the sicp/solver.

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

#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.

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

#58
post #55
post #40

Earlier quoted context omitted.

No, not simple. Analyzing an arbitrary lisp program to determine the lifetimes of all allocated structures reduces to the halting problem, so it's undecidable. You must either restrict the input program or tolerate some leaks.

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.

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

#59

Earlier quoted context omitted.

Neat to see a contender to replace what should've had plenty of adoption in this area: https://en.wikipedia.org/wiki/PreScheme I still don't see a clear answer to junkie's question despite a huge thread. Let's be specific: "Where no GC is used, how exactly do you handle the issue of memory safety? Is it no safety like C, a specific analysis like Rust, or something different entirely?" Far as concurrency, you probably…

Thanks for the links! The short answer is that safety is handled similar to Rust, using lifetime analysis. It's quite a bit more simplistic than Rust at the moment though. Also, some checks are done at runtime (like bounds checking on arrays, when turned on).

Ok. There we go. It's actually what I had in mind for PreScheme. You just gave me more confidence in it.

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

#60
post #18
post #12

Earlier quoted context omitted.

In most Scheme implementations, which this Lisp somewhat resembles, it's permissible to use "(" or "[" as long as the opening bracket matches the closing one. With that choice, each user can have the "esthetic" that is preferred. Personally, I agree that using parentheses exclusively is nicest, but it's not that big a deal either way.

You are right about Scheme. Note that Carp, like Clojure, treats brackets as arrays ( https://github.com/eriksvedang/Carp/blob/master/src/reader.c... ).

I'm not familiar with Clojure, but briefly reviewed the Carp documentation, sparse as it is. The part about "[]" meaning array hadn't quite sunk in when I commented about the syntax. Thanks for pointing that out, the Carp syntax makes perfect sense. I think it's a project worth keeping an eye on as it looks like it could have interesting capabilities.
Post reply on HN