diff mbox series

[bug#65935] gnu: Add ngn-k.

Message ID 20230914054006.18356-1-elaexuotee@wilsonb.com
State New
Headers show
Series [bug#65935] gnu: Add ngn-k. | expand

Commit Message

B. Wilson Sept. 14, 2023, 5:39 a.m. UTC
* gnu/packages/k-lang.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
---
 gnu/local.mk            |  1 +
 gnu/packages/k-lang.scm | 89 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+)
 create mode 100644 gnu/packages/k-lang.scm

Comments

Ludovic Courtès Oct. 18, 2023, 8:49 p.m. UTC | #1
Hi,

"B. Wilson" <elaexuotee@wilsonb.com> skribis:

> * gnu/packages/k-lang.scm: New file.
> * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.

[...]

> +                 (url "https://codeberg.org/ngn/k.git")

This package cannot be included in Guix because what we have above is
not source code: it’s deliberately obfuscated code, it’s not “the
preferred form of the work for making modifications to it” (as the GPL
puts it) in any way.

I hope that makes sense.

Thanks,
Ludo’.
B. Wilson Oct. 20, 2023, 3:06 p.m. UTC | #2
> This package cannot be included in Guix because what we have above is
> not source code: it’s deliberately obfuscated code, it’s not “the
> preferred form of the work for making modifications to it” (as the GPL
> puts it) in any way.
> 
> I hope that makes sense.

I agree that it's super weird, but it's not obfuscated code. Rather, it's the
famously terse Arthur Whitney style. The APL/J/K family of array-oriented
languages all famously have implementations strongly influenced by Whitney, and
ngn-k is just following in that tradition. Those with the relevant domain
knowledge tend to agree that the code is pretty readable.

If you want other examples, see

- Whitney's B interpreter: https://github.com/tlack/b-decoded
- Jsoftware's J interpreter: https://github.com/jsoftware/jsource

The latter is both GPL-3 and actively maintained.
Ludovic Courtès Nov. 20, 2023, 11:28 a.m. UTC | #3
Hi!

"B. Wilson" <elaexuotee@wilsonb.com> skribis:

>> This package cannot be included in Guix because what we have above is
>> not source code: it’s deliberately obfuscated code, it’s not “the
>> preferred form of the work for making modifications to it” (as the GPL
>> puts it) in any way.
>> 
>> I hope that makes sense.
>
> I agree that it's super weird, but it's not obfuscated code. Rather, it's the
> famously terse Arthur Whitney style. The APL/J/K family of array-oriented
> languages all famously have implementations strongly influenced by Whitney, and
> ngn-k is just following in that tradition. Those with the relevant domain
> knowledge tend to agree that the code is pretty readable.

Not being familiar with APL & co., I lack domain knowledge.  However I
do know C, and things like this (from <https://codeberg.org/ngn/k.git>):

--8<---------------cut here---------------start------------->8---
#include"a.h" // ngn/k, (c) 2019-2023 ngn, GNU AGPLv3 - https://codeberg.org/ngn/k/raw/branch/master/LICENSE
I rnk(Ax/*0*/){X(RA(Iv=rnk(xx);P(v<0,v)i(xn,P(v-rnk(xa),-1))v+1)RmM(rnk(xy))RT_A(1)R_(0))}//-1 for mixed rank
I urnk(Ax/*0*/){X(RA(urnk(xx)+1)RmM(urnk(xy))RT_A(1)R_(0))}//assuming unirank
S L fG(OV*p,Nn,Lv)_(O G*a=p,q=v;P(v-q,NL)Ii=0,g=HD/SZ(*a),f=0;W(i<n&&!f,j(g,f|=a[i++]==q))i-=g;j(g,B(a[i]==q)i++)i<n?i:NL)
S L fH(OV*p,Nn,Lv)_(O H*a=p,q=v;P(v-q,NL)Ii=0,g=HD/SZ(*a),f=0;W(i<n&&!f,j(g,f|=a[i++]==q))i-=g;j(g,B(a[i]==q)i++)i<n?i:NL)
  L fI(OV*p,Nn,Lv)_(O I*a=p,q=v;P(v-q,NL)Ii=0,g=HD/SZ(*a),f=0;W(i<n&&!f,j(g,f|=a[i++]==q))i-=g;j(g,B(a[i]==q)i++)i<n?i:NL)
  L fL(OV*p,Nn,Lv)_(O L*a=p,q=v;P(v-q,NL)Ii=0,g=HD/SZ(*a),f=0;W(i<n&&!f,j(g,f|=a[i++]==q))i-=g;j(g,B(a[i]==q)i++)i<n?i:NL)
S A1(fN,Ay=_R(cn[tl]);x(xtt?y:rsz(xN,y)))
//S A1(fBN,Q(xtG)Gv=0;i(xn,v|=xg)P(!(v>> 7&1),x)Ay=aL(xn);Mx(i(xn,yl=xg<0?NL:xg))y)
//S A1(fHN,Q(xtH)Hv=0;i(xn,v|=xg)P(!(v>>15&1),x)Ay=aL(xn);Mx(i(xn,yl=xh<0?NL:xh))y)
//S A1(fIN,Q(xtI)Iv=0;i(xn,v|=xg)P(!(v>>31&1),x)Ay=aL(xn);Mx(i(xn,yl=xi<0?NL:xi))y)
S L t[256];
S X1(fndGx,RmMA(e1f(fndGx,x))Rzc(Lv=gl(x);az(v==(C)v?t[(UC)v]:NL))RE(fndGx(gZ(x)))R_(fN(x))
 RZC_E(Nm=xn;Ay=aL(m);Mx(S4(xw,i(m,yl=t[(UC)xc]),i(m,Hv=xh;yl=v==(C)v?t[(UC)v]:NL),i(m,Iv=xi;yl=v==(C)v?t[(UC)v]:NL),i(m,Lv=xl;yl=v==(C)v?t[(UC)v]:NL)))sqzZ(y)))
[...]
--8<---------------cut here---------------end--------------->8---

… I find it hard to believe they’re “readable” to anyone in the sense of
being the “preferred form” for modifications or even just studying it.
(Heck, even the Makefile has optional whitespace removed, as if trying
hard to make it unreadable!)

I don’t think we have a precedent here; I wouldn’t want to make a
decision based on a personal judgment, and I understand I know nothing
about the APL language family, but someone will have to clarify how
those 1.2K lines of C were written/generated.

I’d love to hear what others think!

Thanks,
Ludo’.
B. Wilson Nov. 20, 2023, 11:52 a.m. UTC | #4
Ludovic Courtès <ludo@gnu.org> wrote:
> … I find it hard to believe they’re “readable” to anyone in the sense of
> being the “preferred form” for modifications or even just studying it.
> (Heck, even the Makefile has optional whitespace removed, as if trying
> hard to make it unreadable!)

It's definitely a gawker at first sight. For comparison, take a look at this in
progress YAML parser of mine:

https://github.com/xelxebar/dayaml/blob/22d20b335bfc99e8e140fee8ca5e7f5f1320f72d/Y.apln

I swear that I sweat blood on this making it as brutally direct and clear as
possible!

> I don’t think we have a precedent here; I wouldn’t want to make a
> decision based on a personal judgment, and I understand I know nothing
> about the APL language family, but someone will have to clarify how
> those 1.2K lines of C were written/generated.

From indirectly knowing the dev, my understanding is that the code is
hand-written. The motivation is basically to decrease the cognitive dissonance
between writing K and writing C. Ideally, you'd want to just write a K
interpreter using K, but that's a whole different can of worms.

The de facto K interpreter, Shakti, is proprietary and expensive, but from
talking to some people on the inside, I gather that it's also written in this
extremely terse style.

> I’d love to hear what others think!
> 
> Thanks,
> Ludo’.

Anyway, thanks for reviving this.
diff mbox series

Patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 924d497057..a4c2c8cda9 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -362,6 +362,7 @@  GNU_SYSTEM_MODULES =				\
   %D%/packages/julia-jll.scm			\
   %D%/packages/julia-xyz.scm			\
   %D%/packages/jupyter.scm			\
+  %D%/packages/k-lang.scm			\
   %D%/packages/kawa.scm				\
   %D%/packages/kde.scm				\
   %D%/packages/kde-frameworks.scm		\
diff --git a/gnu/packages/k-lang.scm b/gnu/packages/k-lang.scm
new file mode 100644
index 0000000000..0c49168639
--- /dev/null
+++ b/gnu/packages/k-lang.scm
@@ -0,0 +1,89 @@ 
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 B. Wilson <elaexuotee@wilsonb.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages k-lang)
+  #:use-module (gnu packages readline)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix git-download)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix packages)
+  #:use-module (guix utils))
+
+(define-public ngn-k
+  (let ((commit "cb36213657b6c5b2fe3bb1c88c4de7fe975f84ed")
+        (revision "1"))
+    (package
+      (name "ngn-k")
+      (version (git-version "0.0.0" revision commit))
+      (source
+        (origin
+          (method git-fetch)
+          (uri (git-reference
+                 (url "https://codeberg.org/ngn/k.git")
+                 (commit commit)))
+          (file-name (git-file-name name version))
+          (sha256
+            (base32 "1140avqsqaa1pyh937rcd04snbkcgngmkg3dkmsbj6kw0jnrgf1z"))))
+      (build-system gnu-build-system)
+      (inputs (list rlwrap))
+      (arguments
+       `(#:make-flags (list (string-append "CC=" ,(cc-for-target)))
+         #:test-target "t"
+         #:phases
+         (modify-phases %standard-phases
+          (replace 'configure
+            (lambda* (#:key outputs #:allow-other-keys)
+              (let* ((out (assoc-ref outputs "out"))
+                     (k (string-append out "/k")))
+                (substitute* "repl.k"
+                  (("^#!k") (string-append "#!" k "\n"))))))
+          (replace 'build
+            (lambda* (#:key make-flags #:allow-other-keys)
+              (let ((build-target "k"))
+                (apply invoke "make" `(,@make-flags ,build-target)))))
+          (replace 'install
+            (lambda* (#:key inputs outputs #:allow-other-keys)
+              (let* ((out (assoc-ref outputs "out"))
+                     (bin (string-append out "/bin"))
+                     (k (string-append bin "/k"))
+                     (rlwrap (string-append
+                               (assoc-ref inputs "rlwrap")
+                               "/bin/rlwrap")))
+
+                 (define* (rlwrap-prog prog #:key rlwrap (sh (which "bash")))
+                   (let* ((real-prog (string-append (dirname prog) "/."
+                                                    (basename prog) "-real"))
+                          (prog-tmp (string-append real-prog "-tmp")))
+                     (link prog real-prog)
+                     (call-with-output-file prog-tmp
+                       (lambda (port)
+                         (format port
+                                 "#!~a~%exec -a \"$0\" \"~a\" \"~a\" \"$@\"~%"
+                                 sh rlwrap (canonicalize-path real-prog))))
+                     (chmod prog-tmp #o755)
+                     (rename-file prog-tmp prog)))
+
+                (mkdir-p bin)
+                (copy-file "repl.k" (string-append bin "/krepl"))
+                (copy-file "k" k)
+                (rlwrap-prog k #:rlwrap rlwrap)))))))
+      (home-page "https://codeberg.org/ngn/k")
+      (synopsis "Implementation of the K6 vector programming language")
+      (description "ngn/k is a simple fast vector programming language, an
+implementation of the K6 dialect of K.")
+      (license license:agpl3))))