When writing a parser in a low-level language like C, how does one allocate strings with good performance? I can't find anything online about this problem, but it seems significant to me.

I've settled on allocating a large char array up front, and exposing two functions.

void add_char(builder* b, char c);
char* end_string(builder* b);

`end_string` adds a null character to finish the current string, and returns a pointer to where that string started.

Is this a good approach?

Can you spot the bug? I wrote this code a couple days ago and am only now testing it.

for (size_t i = cs.name_stack.size - 1; i >= 0; i--) {

I'm not sure how I feel about passing parameters by reference in D and C++. I like it because it abstracts the integer nature of the pointer, so I can guarantee that pointer arithmetic mistakes don't exist. I dislike it because the caller syntax make no distinction between ref and value parameters, so I can't tell if a function will modify a variable.

Related is how D overloads `.` to be used where `.` and `->` are used in C/C++.

By switching from malloc to a pool allocator, I improved my lambda calculus parser from 1.16 seconds for 300k lines of code to 1.25 seconds for 500k. Not too shabby I would say.

Close only counts in horseshoes, hand grenades, and hashing algorithms.

Of course, T* and T** may refer to arrays and 2D arrays, so the meaning is overloaded and must be communicated out-of-band, but that's not really the point here.

My affection for functional programming makes me want to only take values and return values, but I've begun to appreciate data-oriented design through watching guys like Jonathan Blow and Mike Acton. There are two many slow/memory-hungry programs these days.

I haven't written much code which has to manually manage memory. I am doing so now, and I'm struggling to understand when to malloc, when to use the stack, where to allocate, and where to modify/fill memory.

It seems to me that for function parameters:

T = caller allocates, caller fills
T* = caller allocates, callee modifies
T** = callee allocates, callee modifies

The matrix is completed when returning T, which means callee allocates, callee modifies.

Does this pattern make good sense?

To leave #vim with a non-zero exit code use `:cq`.

Useful to abort a #Git commit or a #Bash `fc` command

Go programs might compile fast but Scala programs give you the opportunity to spend time thinking about your life choices and how you ended up writing enterprise software.

#GoLang #Scala

When your only hammer is JavaScript, everyone else's thumb looks like a nail

In my type, I have the constructors

Var ...
Val ...
Lam String Expr
App Expr Expr

For HM , these are not sufficient to handle recursion, so we need Let-polymorphism, for which we have

Let String Expr Expr

Seems to me that the following forms are equivalent:

Let var x e === App (Lam var e) x

In other words, Let is just a special case for immediately applied lambdas, so I can avoid adding it to my type, right?


Thank you for your email. Unfortunately I will not be reading it because it uses HTML rather than plain text. Please consider resending this message in plain text format. In the interest of making the web better and safer, I would also suggest making this the default for all of your emails.

If you choose not to comply and are annoyed by this reply to all of your emails, reply with BLOCK ME in the subject line.

Consult useplaintext.email/ for help and the reason to use plain text.

In , how do I use the vim plugin that ships with ? The `fzf-share` command gives me a path to a directory that contains scripts that help customize a shell, but I don't see anything for vim in there.

Looking at the FZF nixpkgs file, it looks like there is indeed a patch being applied to the included vim file; I just don't know how to get to it.

Anyone got any tips? I could just copy the file into my vim configuration, but this seems less good.


I look forward to the day when Mastodon clients support markdown. Is there a reason they don't? Link support might be a bad idea for security, but code block formatting would be both safe and very useful.

@fedilab Is there any reason why this feature doesn't already exist? (other than lack of time or it hasn't been thought of)

I want to make a library that operates on an extremely simple AST to use whenever I need a quick and easy type inference engine. As long as more complex ASTs can be converted to the simple one, the type of an expression can be inferred.

For example, `IF cond then-clause else-clause` converts to `lambda : bool -> 'a -> 'a -> 'a`; that is, type inference does not care how IF behaves, but only about the type of its arguments.

All you can get from this library is the type of the whole expression.

I've just been looking at the existing plugin for . It looks like most of it could stay pretty much exactly the same for an 2 plugin. The trouble is that they have the same file extension, so I'd have to manually `:set ft=idris2` or use some global variable to say which version I want to use by default.

@edwinb Just built Idris 1 master from source and am now using it to build Idris 2. The second version is of course much less painless to build than the first version because there are no dependencies to download. Perhaps that's a reason why it's so much faster; the memory footprint of the compiler is much smaller?

Show more
Functional Café

functional.cafe is an instance for people interested in functional programming and languages.