by noelwelsh on 9/8/2022, 6:01:41 AM
by bjarneh on 9/8/2022, 7:47:20 AM
> Variables are not unique. You can declare multiple values for the same variable name using ":=" and append in the stack. If you want to edit the last declaration, just user simple "=" operator. To remove the last variable with specific name in stack, use "del varname"
Isn't this very confusing in almost all instances?
by henriquegogo on 9/8/2022, 4:14:05 AM
What is Kamby? A small, embeddable and convenient language for who want to use and understand what is happening behind the scenes. The core is just ~400LOC and binary has just 20kb.
by camgunz on 9/8/2022, 7:01:28 AM
Hi! This looks super cool. I'm curious at what inspired you to implement variable stacking. At first I was like "whaaaaat", but then I thought, "maybe everything being a stack is useful?" Maybe for like immutable state or something.
Anyway again very inspiring :)
by cglong on 9/8/2022, 8:10:16 AM
This should probably be marked a Show HN.
by qwerty456127 on 9/8/2022, 10:12:01 AM
By the way, I always wondered why not just take a lisp, put every single thing (even an operator) on a separate line and indent every level of parentheses with a space or two (4 spaces is too much - deep nesting would go too much to the right). So there would be no need for the parentheses in most cases.
by melony on 9/8/2022, 5:20:41 AM
Did someone just reinvent Rebol/Red?
by mikewarot on 9/8/2022, 5:08:44 AM
Browsing the source code, I came across something completely unexpected. I didn't know you could put code in structs like this sample from kamby/kamby.c
struct KaNode *ka_add(struct KaNode *node, struct KaNode **env) {
if (node->type == KA_STR && node->next->type == KA_STR) {
struct KaNode *output = ka_str(node->str);
strcat(output->str, node->next->str);
return output;
}
return ka_num(node->num + node->next->num);
}
Is this legal? If so, I'm going to use the heck out of it for my version of STOIC.[Edit] Ok.. thanks for the help.. I'm used to seeing function types declared AFTER the parameters because pascal habits die hard. It looked like a run of the mill structure declaration to me.
by andrewshadura on 9/8/2022, 7:55:30 AM
So, it's like Hy, only the other way around?
by esjeon on 9/8/2022, 2:10:03 PM
I can feel that this is surely a fun project, full of decent tricks on the code level. Still, tricks are just tricks, and won't provide firm foundation. It's gonna be difficult to engineer either an application or the language itself in the current state. I kinda wonder what OP is planning after this.
by yafinder on 9/8/2022, 11:34:33 AM
Ummmm
planet = [ name := 'World' nick := 'Earth' ]
'Hello, ' + (planet :: {WAT})
Output: 10585168
by GranularRecipe on 9/8/2022, 7:50:07 AM
If I visit the website, Firefox warns of potential security risk because the connection is not encrypted.
by kazinator on 9/9/2022, 8:24:34 AM
I made a small evaluator in TXR Lisp for what appears to be my understanding "Kamby-like" semantics.
$ txr -i kamby.tl
Syntactic toffee recipe: melt butter over low heat, stir in Lisp macros.
1> (kamby-repl)
kmb> (let dz (/ 10 0))
** error: /: division by zero
kmb> (let a 1)
a
kmb> a
1
kmb> (let foo [(let bar1 42) (let bar2 73)])
foo
kmb> foo
#<kamby-env:(bar2 bar1)>
kmb> foo.bar1
42
kmb> foo.bar2
73
kmb> (set a 4)
4
kmb> a
4
kmb> (set a (* 2 a))
** warning: unbound variable a
** error: unbound variable a
Errors out at the end because unknown forms are evaled as Lisp, and Kamby variables are not Lisp variables.Mostly this was to play with the "construct environment tree as-you-go, with qualified pathname access" idea.
Code:
(defstruct kamby-env ()
bindings ;; assoc list
next-env ;; kamby-env object or nil
(:method extend (me sym value)
(upd me.bindings (acons sym value)))
(:method lookup (me sym)
(assoc sym me.bindings))
(:method delete (me sym)
(let ((binding (assoc sym me.bindings)))
(upd me.bindings (remq binding))))
(:method print (me stream pretty-p)
(format stream "#<~s:~s>" 'kamby-env [mapcar car me.bindings])))
(defvar *kamby-env* (new kamby-env))
(defun kamby-error (form fmt . args)
(error `~s: ~s: @fmt` 'kamby-eval (if (atom form) form (car form)) . args))
(defun kamby-eval (form)
(let ((e *kamby-env*))
(match-case form
((let @var @expr) e.(extend var (kamby-eval expr))
var)
((set @var @expr) (let ((binding e.(lookup var)))
(if binding
(rplacd binding (kamby-eval expr))
(kamby-error form "no such variable: ~s" var))
(cdr binding)))
((del @var) (unless e.(delete var)
(kamby-error form "no such variable")))
(@(symbolp @var) (let ((binding e.(lookup var)))
(if binding
(cdr binding)
(kamby-error form "no such variable: ~s" var))))
;; TXR Lisp qref syntax a.b.c.d <--> (qref a b c d)
((qref . @vars) (let (value)
(while vars
(let* ((var (pop vars))
(binding e.(lookup var)))
(unless binding
(kamby-error form "no such variable: ~s (when resolving ~s)" var form))
(set value (cdr binding))
(if (and vars (not (typep value 'kamby-env)))
(kamby-error form "~s isn't an environment object; cannot lookup ~s"
value (car vars)))
(set e value)))
value))
;; TXR Lisp dwim brackets syntax [a b c] <--> (dwim a b c)
((dwim . @forms) (let ((*kamby-env* (new kamby-env next-env e)))
[mapdo kamby-eval forms]
*kamby-env*))
(@else (eval else)))))
(defun kamby-repl ()
(whilet ((line (progn (put-string "kmb> ") (get-line))))
(catch
(prinl (kamby-eval (read line)))
(error (x)
(put-line `** error: @x`)))))
by zubairq on 9/8/2022, 4:55:24 AM
Where are the macros?
by c3534l on 9/8/2022, 4:53:59 AM
And yet its still filled with unncessary parentheses like an involuntary tic.
I think it's great that people create new languages. It's fun and a good learning exercise. For this language I'm very unclear on the scoping rules, and the dynamic environments look quite hard to reason about. I can't imagine ever using the language, but I'm pleased the creator is exploring some off beat ideas.