Programming thread

  • Want to keep track of this thread?
    Accounts can bookmark posts, watch threads for updates, and jump back to where you stopped reading.
    Create account
Lua is language that you use in order to embed scripts into your program if you don’t know any better because if you did you would have used Scheme.
of course if you want to use scheme you have to find an implementation (they're all pretty incompatible) that doesn't suck in some way (guile? doesn't work on windows. chibi? slow as fuck. chicken? not really made for embedding. something else? you'll probably run into some kind of weird problem)
meanwhile with lua you have puc rio lua and luajit which is mostly compatible except for how it's ten times as fast or luau if you're a fucking degenerate
hopefully in a while we will see schemes that are as good for embedding as lua but we aren't quite there yet
i think right now guile is the most powerful "embed it in your c++ monstrosity" scheme. it was designed to be the gnu ubiquitous intelligent language for embedding, after all
I remember a blog posts from years ago about how Forth is the language people love to implement and never use and that is true for me.
some think scheme is the worst about that, but i encounter way more shit written in scheme than i do in forth
then again i think forth is best inside of a microcontroller in space or something. some languages just have a time and a place really
on the other hand, i think you could jam scheme just about anywhere and have it work well enough
 
then again i think forth is best inside of a microcontroller in space or something. some languages just have a time and a place really
on the other hand, i think you could jam scheme just about anywhere and have it work well enough
With constrained enough resources I can see Forth being useful. Outside of that I think it's just a fun toy. Scheme seems to have a completely different problem where no one can agree on a base set of libraries so everyone just writes their own.

I have an unrelated issue with Scheme and other scripting languages that makes them easy to integrate but not as good for standalone programs: their lack of type safety. If you aren't going for a mainstream language then a nice strongly and statically typed language like Haskell makes robust programming so much easier.
 
Scheme seems to have a completely different problem where no one can agree on a base set of libraries so everyone just writes their own.
this actually might not be so bad for embedded scheme because lua has a terrible standard library too
usually when you're extending some application, you're working with types and functions provided by the application, and the application developers have to provide them all no matter how rich the standard library is
i think scheme would be a very good scripting language if you had a couple implementations that had apis that closely mimicked the behavior of lua (it has this neat stack-based model that makes it easy to interact with from c while also allowing compacting gc and nice things like that)
I have an unrelated issue with Scheme and other scripting languages that makes them easy to integrate but not as good for standalone programs: their lack of type safety.
doesn't seem to stop the gnu project from making large complicated applications in lisp and scheme though
honestly dynamic typing isn't as bad as people make it out to be when you're being nice and careful (every programmer should be at least a bit careful)
 
of course if you want to use scheme you have to find an implementation (they're all pretty incompatible) that doesn't suck in some way (guile? doesn't work on windows. chibi? slow as fuck. chicken? not really made for embedding. something else? you'll probably run into some kind of weird problem)
meanwhile with lua you have puc rio lua and luajit which is mostly compatible except for how it's ten times as fast or luau if you're a fucking degenerate
hopefully in a while we will see schemes that are as good for embedding as lua but we aren't quite there yet
i think right now guile is the most powerful "embed it in your c++ monstrosity" scheme. it was designed to be the gnu ubiquitous intelligent language for embedding, after all
Chez. Also guile is buggy af so the only reasons to use it is because it got defmacro instead of the retarded define-syntax nonsense and the fact that Guix uses it.
 
Using the C interface ie the way that you embed any language. Preferably one less pain full to use than LUA
where exactly do you load libchez.so from so you can start a chez vm from c, communicate with it, and evaluate scheme extension programs from your c program
 
where exactly do you load libchez.so from so you can start a chez vm from c, communicate with it, and evaluate scheme extension programs from your c program
You ship the kernel library with your program or link it statically ie the same way that you do it with lua. It is all in the documentation.
EDIT: Embeding example

Makefile
Makefile:
DIST := pb

run: main
    ./main

petite.boot: ChezScheme/${DIST}/boot/${DIST}/petite.boot
    cp ChezScheme/${DIST}/boot/${DIST}/petite.boot .

scheme.boot: ChezScheme/${DIST}/boot/${DIST}/scheme.boot
    cp ChezScheme/${DIST}/boot/${DIST}/scheme.boot .

main: main.c scheme.boot petite.boot
    gcc -I ChezScheme/${DIST}/boot/${DIST}/ -o main main.c ChezScheme/${DIST}/boot/${DIST}/libkernel.a ChezScheme/${DIST}/zlib/libz.a -lm ChezScheme/${DIST}/lz4/lib/liblz4.a

.PHONY: run

main.c
C:
#include <scheme.h>
#include <stdio.h>

int nigger() {
  printf("C NIGGER\n");
  return 2137;
}

int main() {
  Sscheme_init(NULL);
  Sregister_boot_file("./petite.boot");
  Sregister_boot_file("./scheme.boot");
  Sbuild_heap(NULL, NULL);

  Sregister_symbol("nigger", &nigger);
 
  Sscheme_program("nigger.scm", 0, NULL);
 
}

nigger.scm
Code:
(import (chezscheme))

(display "SCM NIGGER\n")

(define c-nigger
  (foreign-procedure "nigger" () integer-32))

(display (c-nigger))
(newline)
 
Last edited:
how Forth is the language people love to implement and never use and that is true for me
There are folks who would argue this is true of Scheme, too. The downside of Forth is that it's a stack language and forces you to think like RPN. The upside is that our CPUs have a lot of nice stack manips built in. If I'm integrating with C, Ruby's my usual first choice. It's all about what you're doing, though. Dwarf Fortress's initial rollout of Lua was to replace text config files. You're right that I'd probably go with Scheme if given the choice between Scheme and Forth, but the older I get, the more I like S-expressions. Forth turns S-expressions on their heads to save some brackets but that really obscures the logical groupings in the code, which S-expressions enforce vigorously.

Any of y'all niggers fuck with Shen? https://shenlanguage.org/
 
Forth turns S-expressions on their heads to save some brackets but that really obscures the logical groupings in the code
forth actually doesn't need to use postfix to save the brackets, the postfix is what makes the stack shit map cleanly to the code
you could also write prefix notation without parentheses if you always knew how to place the parentheses from context clues like "+ always takes two arguments"
example: + + 2 2 2 would be the parentheses-free version of (+ (+ 2 2) 2) and + 2 + 2 2 would be (+ 2 (+ 2 2))
of course a form of s-expressions without explicit grouping would probably be really painful which is why we have all the parentheses

also there's absolutely nothing stopping you from making scheme use postfix-based notation. all it would take is a few evaluator changes or perhaps a syntax-rules macro that i'm a bit too retarded to write at this time
 
The downside of Forth is that it's a stack language and forces you to think like RPN. The upside is that our CPUs have a lot of nice stack manips built in
I think that is exactly why Forth isn't really a modern language unlike other old languages such as Scheme. It trades ease of the user for ease of the computer and we no longer need things to be easy for the computer. If I had to toggle switches to input machine code to bring up a machine I'd want something simple and relatively powerful like Forth. When I can use a multi-GHz computer to compile any language I want and an RP2350 costs $0.80 Forth loses its relevance.

I do still think implementing Forth is useful and fun. Jonesforth is a great tutorial even if you want to use a real architecture like MIPS or POWER.
 
forth actually doesn't need to use postfix to save the brackets, the postfix is what makes the stack shit map cleanly to the code
My wording was me taking minor creative license with what Forth is doing. Postfix notation's lack of clarity is what I was griping about. English grammar is subject-verb-object, but verb-object in the imperative case, which maps onto S-expressions: (verb direct-object indirect-object et-cetera), (add 69 420) though I used "add" not "+" for parallelism reasons. And yeah, I know you can twist both Scheme and Forth to use other orders.
 
I'm getting pretty interested in using protobuf with my C projects, but I wanted to ask if anyone has used it and what your impression was
 
I'm getting pretty interested in using protobuf with my C projects, but I wanted to ask if anyone has used it and what your impression was
Protocol Buffers are the canonical way to do binary serialization in SWI Prolog. They're kind of an overwrought solution, but they're engineered for efficiency so I'll forgive a fair bit. Never used em with C but they're probably great there too.
 
Protocol Buffers are the canonical way to do binary serialization in SWI Prolog. They're kind of an overwrought solution, but they're engineered for efficiency so I'll forgive a fair bit. Never used em with C but they're probably great there too.
I find them attractive because it’s a tagged TLV format, and the boilerplate isn’t that bad
All you have to do basically to switch is swap your heap functions with the generated ones, and you have to use heap strings, but neither is a huge deal

My only hesitation is that you have to define nested structs separately, and I’m a bit of a pedant about how I lay out my structs
 
My wording was me taking minor creative license with what Forth is doing. Postfix notation's lack of clarity is what I was griping about. English grammar is subject-verb-object, but verb-object in the imperative case, which maps onto S-expressions: (verb direct-object indirect-object et-cetera), (add 69 420) though I used "add" not "+" for parallelism reasons. And yeah, I know you can twist both Scheme and Forth to use other orders.
I haven't used Forth, but its ordering seems intuitive to me on sequences of transformations, which match the order of English. Not because of SVO order, but because we tend to list actions in the same order they happen, e.g. "I watered, fertilized, and pruned the plants".

Compare:
Code:
(third (second (first thing)))
vs
Code:
thing first second third


Of course, with LISP, a macro could be used to order things this way, and sure enough, a common macro in Clojure (and probably elsewhere) is the "thread" macro, used like so:
Code:
(->> thing first second third)
Javascript's array prototype functions are a popular way to express things in a similar way, e.g.
Code:
thing.map(func).reduce(func, acc).filter(func)
Methods on objects also kind of enable Subject-Verb-Object (dog.eat(food)) order in some cases, but I think trying to make programming languages look or feel like natural languages is usually misguided (See: COBOL)
 
another way to deal with long chains of transformations would probably be to try to design things so you don't need to take a thing and then do three other things to it in a big ugly chain
no matter what kind of macros or convenient syntax you have, the underlying complexity doesn't really ever go away

a macro that applies multiple functions to a piece of data is very nice, but nothing beats making the program so simple that such a macro is not necessary
of course, the art of making code that simple is so fucking hard, so hopelessly painful, that there is an entire industry around making books on the subject. very few of these books have anything that isn't complete bullshit
 
Of course, with LISP, a macro could be used to order things this way, and sure enough, a common macro in Clojure (and probably elsewhere) is the "thread" macro, used like so:
The basic pipe operator in third-party R package magrittr, %>%, became so popular that it's now a core part of R (as |>) since 4.1.0.
of course, the art of making code that simple is so fucking hard, so hopelessly painful, that there is an entire industry around making books on the subject. very few of these books have anything that isn't complete bullshit
What are some of the few good ones?
 
What are some of the few good ones?
read all of them and find out. actually a serious answer unfortunately

i'd say it's like learning how to be an excellent painter: i think the only way to truly become great at it is years and years of practice and observing how you inevitably fuck up over and over again
there are some things you just can't learn from a book, and i think that nameless thing, that i am calling "so simple that such a macro is not necessary" and terry called DIVINE INTELLECT, is simply one of these things

reading books about programming clearly will get you to a low level of understanding. gaining familiarity with the cultures of languages with extremely varied paradigms from haskell to forth to prolog will teach you slightly more. programming for a few decades with all that in mind will teach you the things that simply reading them in a book can't
 
I haven't used Forth, but its ordering seems intuitive to me on sequences of transformations, which match the order of English. Not because of SVO order, but because we tend to list actions in the same order they happen, e.g. "I watered, fertilized, and pruned the plants".

Compare:
Code:
(third (second (first thing)))
vs
Code:
thing first second third


Of course, with LISP, a macro could be used to order things this way, and sure enough, a common macro in Clojure (and probably elsewhere) is the "thread" macro, used like so:
Code:
(->> thing first second third)
Javascript's array prototype functions are a popular way to express things in a similar way, e.g.
Code:
thing.map(func).reduce(func, acc).filter(func)
Methods on objects also kind of enable Subject-Verb-Object (dog.eat(food)) order in some cases, but I think trying to make programming languages look or feel like natural languages is usually misguided (See: COBOL)
Racket has a thingy (set of macros) for this. They call it Qi: An Embeddable Flow-Oriented Language.
An embeddable, general-purpose language to allow convenient framing of programming logic in terms of functional flows. A flow is a function from inputs to outputs, and Qi provides compact notation for describing complex flows.
Tired of writing long functional pipelines with nested syntax like this?
Code:
(map f (filter g (vector->list my-awesome-data)))
Then Qi is for you!
Code:
(~> (my-awesome-data) vector->list (filter g) (map f))
But wait, there’s more: Qi isn’t just a turbo-charged threading language. It supports multiple values and a suite of other operators for describing computations:
Code:
(define-flow average
  (~> (-< + count) /))
As the quote suggests, it has way more than just a threading operator. I haven't messed around with it yet, but I saw it while flipping through the racket docs a while back and thought it looked cool.
 
Back
Top Bottom