Dale – A Lisp-flavoured C
github.com
github.com
This is not a critique; I'm just curious.
Additionally, my comment was not directed solely at Dale, but new language announcements in general.
Sadly, I lost that tool in a triple, HD crash along with most work. Loved it, though. I never even fully learned LISP or C but the subsets let me crank out tons functionality really fast then run it through optimizing C compilers.
I'm just curious - I'm not passing judgement at all. Hell, I've a C++ compiler I've been working on for a while (it doesn't get much attention). Why? It forces you to confront the spec (all +1200 pages of it) and to understand the nuances of the language. I don't ever expect my compiler to be released publicly or used in production, but it's for my own personal growth and to increase my understanding of the language, which makes me a better C++ developer. I'm more of a data systems programmer (I work in finance), so working on a compiler exposed me to other areas I wasn't familiar with (parsers, grammars, ASTs, etc).
But, more substantive answers to the questions I've asked of a language(s) designer(s) can provide insight into what the language is well (or poorly) suited for or for it's potential longevity. If it was created for fun by the author, it's probably significantly less likely to have large adoption.
Unfortunately, I now commute 2 hours a day in the car, so my spare reading time is greatly diminished, so I don't have 40 minutes twice a day to read something novel like this in detail on the train like I used to have.
And a lot of the popular languages are pretty terrible.
Im also sceptical of that designing the language with practicallity in mind would make it signifficantly more useful.
You'd have to judge each of them by their own merit.
"Google, read me Hacker News!"
"Are you sure? Looks like nothing interesting this morning. Oh wait, Aphry just posted something. Would you like to hear it?"
"Sure!.. Wait, Google, why don't you drive, and I'll read it!"
"Sounds great. Should I start the espresso machine as well?"
It could well be a cultural thing: for some people, "creating a new language" is a serious undertaking, but for others (especially those exposed to Lisp and Scheme), creating a new language is something you might do if you're curious about something. At the end of the day, creating a language just isn't all that hard to give it so much thought.
Steps: 1. Create a new language in which the problem is trivially expressed. 2. Solve the problem in the new language.
Lisp / Scheme are ideal for this.
Example: solve some sort of puzzle game. Create a data structure that represents the board, a game piece and a move. Operators upon these. Given a board and a legal move, return a new board with the move applied. Given a board, give all of the possible legal moves (for a particular player if this a multi-player game instead of a puzzle).
Once you have that language it becomes easy to use your favorite off the shelf search algorithms. Depth first. Breadth first. A*. Etc.
But, this is probably not the same reason to create a "language" as the article. And the notion of "language" is quite different.
Doesn't a language have to be turing complete to be a language?
This is true, but hermitdev's point still stands: why was this particular idea pleasurable? Why c and lisp? Is it because they want a fast compiling lisp? Did they like the syntax of c but find it easier to implement in lisp's tree-like structure?
What's the character motivation in this scene?
Like look at this fragment from https://github.com/tomhrr/dale/blob/master/src/dale/Function...
bool
isUnoverloadedMacro(Units *units, const char *name,
std::vector<Node*> *lst,
Function **macro_to_call)
{
std::map<std::string, std::vector<Function *> *>::iterator
iter;
Function *fn = NULL;
for (std::vector<NSNode *>::reverse_iterator
rb = units->top()->ctx->used_ns_nodes.rbegin(),
re = units->top()->ctx->used_ns_nodes.rend();
rb != re;
++rb) {
iter = (*rb)->ns->functions.find(name);
if (iter != (*rb)->ns->functions.end()) {
fn = (*iter->second)[0];
break;
}
}
This is not even up to good C++ coding practice, what with the raw exception-unsafe pointers and whatnot.Name represented as char * ? I stopped using C strings in C++ code around 1998, other than in low level code interfacing with things that require them. Kids that were born then are now in college. If you're doing Lisp manipulation, you want anything that is a "name" of some kind to be an interned symbol, which quickly compares to another symbol variable as a pointer.
Why would you do all this to yourself, if (or so it seems) you know enough about Lisp to want a C-like language in S-exp syntax?!
The increasing adoption of code review tools like Gerrit is one of the best things that has been happening in recent years.
No piece of code I've written in the past few years on the job has gone into the stream without the approval of several people.
Frequently, it had to be revised. More than once.
Just take this random example http://www.kylheku.com/cgit/txr/tree/rand.c#n138 . The abuse of the preprocessor for checking pointer size is definitely poor practice.
Because of this I won't even bother thinking critically about the language itself. (Though it does make my eyes bleed to read.)
In summary, your comment is low effort, and I hope more people call you out for it.
So, your parody is interesting but maybe counterproductive. It doesn't change the fact that the OP is already using language that isn't great for this in a way that doesn't inspire confidence. That's worth noting always as shitty implementations can lead to bugs for early adopters. Best to call out problems in parent's work in threads on that, a mailing list or repo if there is one, etc.
I would be more open to such criticism from users of the software. In my opinion that type of comment is worse than backseat driving, at least in that case the passenger is a stakeholder.
By that logic, I'd have to lease a mainframe for millions of dollars before critiquing aspects of their offering. Likewise, I'd have to pay Oracle $70,000 per processor. If flawed FOSS, I'd have to go through the pain of setting up and using it instead of submitting the flaw. Your analogy would apply better if you said "person in back seat shouting about an obstacle they're about to hit to driver that fell asleep."
Realistically, though, better to critique than use flawed products unless it gets the job done enough to be worth using anyway. No need to become a stakeholder.
[Non-moving-target reference with commit hash: http://www.kylheku.com/cgit/txr/tree/rand.c?id=6ca6be767f8ac... ]
The problem with your statement is that it isn't true.
Selecting code alternatives using #ifdef is one of the benign uses of the C preprocessing feature, exemplifying "use it like this" in contrast with "bad" uses. In many a coding guide you can it recommended to use the preprocessor to do a little #ifdef here and there, while avoiding crazy macros. (Of course, code can turn into a hairball of nested #ifdefs, which everyone rightfully hates, but this sort of use is not characterized with the word abuse. It is just use.)
We could split the function into two copies for those alternatives, put them into separate files and then have something slick in the Makefile to pick the correct file (not the GNU Make ifeq syntax, of course; that would be ironic).
However, those two functions would then contain lots of repeated code also. If something has to change, two identical parts in similar functions have to be updated.
Okay so then we could refactor the function so that all the common things are in a generic part, and then the switched pieces are in a helper inline function (included from one of two different files, etc).
It's not clear that it would improve things in that particular case.
I really have no idea what, if anything, would be worth doing, and that could be due to my mental limitations. If someone sends me a plan about how to refactor that code in a good way (just an outline with bullet points in plain language, no code) I will seriously consider it, and possibly do the work.
All your critique would also apply if this were written in idiomatic C. C pointers are exception unsafe by definition because there are no exceptions. STL containers don't throw exceptions other than out-of-range exceptions, which isn't much better or worse than the access violation you'd get for the same bug in plain C.
One good reason why the code might be like this is the author doesn't know all 2568287 C++ features that are required to write modern idiomatic C++ - but the author does know C and std::map.
I can definitely see a Lisper thinking this rationale is so obvious that it does not require mentioning.
But they also seem to offer namespaces, type inference (even through macros), sum types, anonymous functions, overloaded functions, a form of runtime introspection, and a bunch of goodies like containers in the stdlib.
Quite an offering, I'd say.
" Its development was prompted by the Common Lisp and Scheme tutorials that contrast syntactic macros with C preprocessor macros, and wanting to see whether syntactic macros could work in a lower-level language. " -Tom Harrison [1]
[1] https://groups.google.com/forum/#!msg/dale-lang/h73oNq5U6MQ/...
> Somewhat related Free Software projects:
> * Pre-Scheme is a GC-free (LIFO) subset of Scheme
> * Carp is "a statically typed lisp, without a GC"
> * newLISP uses "One Reference Only" memory management
> * MLKit uses region inference (and a GC)
> * Linear Lisp produces no garbage
> * Dale is basically C in S-Exprs (but with macros)
> * ThinLisp is a subset of Common Lisp that can be used without GC
Some of the shouts out to thinlisp and other systems that did similar to this before are interesting. Very interesting.
I mean, it's not C. And it is a lisp.
So doesn't it make sense to call it "lisp with a flavor of C" rather than the other way around?
Cool project!
On another note, the lack of garbage collection at the very least would make Dale very abnormal in terms of being a Lisp v. some other language that happens to embrace s-expressions for its syntax.
No? So what then makes it Lisp-flavored? CONS CAR CDR and parentheses?
See for example C-MERA:
From the CLASP page:
> Clasp is a new Common Lisp implementation that seamlessly interoperates with C++ libraries and programs using LLVM for compilation to native code. This allows Clasp to take advantage of a vast array of preexisting libraries and programs, such as out of the scientific computing ecosystem. Embedding them in a Common Lisp environment allows you to make use of rapid prototyping, incremental development, and other capabilities that make it a powerful language.
you wrote:
> This project uses LLVM's API, which is sadly difficult to utilize outside of C++.
I would guess that you could use LLVM's API via CLASP. The author initially wrote ( https://drmeister.wordpress.com/2014/09/18/announcing-clasp/) :
> Clasp exposes the LLVM C++ library within Common Lisp providing a rich, dynamic, programming environment for exploring the LLVM library and for writing new compilers that generate LLVM-IR.
Then you could write the parser/compiler in Lisp, which supports manipulating s-expressions on a simpler level than C++ does.
2) "Why isn't it written in Lisp?" It's 42% C++ according to GitHub.
3) Based on a hunch and past experiences, I'm going to ignore any follow ups on this thread.
EDIT: And now I look like a jerk because lispm replaced his terse comment with a fuller comment. My apologies for even engaging in the first place. Should have known better.
Anyway, Dale looks like a cool project.