drym-org / qi

An embeddable flow-oriented language.
58 stars 12 forks source link

Support more literal classes #85

Closed countvajhula closed 1 year ago

countvajhula commented 1 year ago

Summary of Changes

This adds support for more literal classes: vectors, boxes and (maybe) prefabs.

Public Domain Dedication

(Why: The freely released, copyright-free work in this repository represents an investment in a better way of doing things called attribution-based economics. Attribution-based economics is based on the simple idea that we gain more by giving more, not by holding on to things that, truly, we could only create because we, in our turn, received from others. As it turns out, an economic system based on attribution -- where those who give more are more empowered -- is significantly more efficient than capitalism while also being stable and fair (unlike capitalism, on both counts), giving it transformative power to elevate the human condition and address the problems that face us today along with a host of others that have been intractable since the beginning. You can help make this a reality by releasing your work in the same way -- freely into the public domain in the simple hope of providing value. Learn more about attribution-based economics at drym.org, tell your friends, do your part.)

countvajhula commented 1 year ago

I attempted to support prefab literals the same way as the others:

diff --git a/qi-lib/flow/aux-syntax.rkt b/qi-lib/flow/aux-syntax.rkt
index b47bb86..cf4604f 100644
--- a/qi-lib/flow/aux-syntax.rkt
+++ b/qi-lib/flow/aux-syntax.rkt
@@ -19,6 +19,7 @@
          expr:byte-regexp
          expr:vector-literal
          expr:box-literal
+         expr:prefab-literal
          ;; We'd like to treat quoted forms as literals as well. This
          ;; includes symbols, and would also include, for instance,
          ;; syntactic specifications of flows, since flows are
@@ -45,6 +46,9 @@
 (define-syntax-class box-literal
   (pattern #&v))

+(define-syntax-class prefab-literal
+  (pattern #s(_ ...)))
+
 (define-syntax-class (starts-with pfx)
   (pattern i:id
     #:when (string-prefix?
diff --git a/qi-test/tests/flow.rkt b/qi-test/tests/flow.rkt
index d79efce..580a0e1 100644
--- a/qi-test/tests/flow.rkt
+++ b/qi-test/tests/flow.rkt
@@ -49,6 +49,7 @@
      (check-equal? ((flow #(1 2 3)) 2) #(1 2 3) "literal vector")
      (check-equal? ((flow #&3) 2) #&3 "literal box")
      (check-equal? ((flow #&(1 2 3)) 2) #&(1 2 3) "literal collection in a box")
+     (check-equal? ((flow #s(dog "Fido")) 2) #s(dog "Fido") "literal prefab")
      (check-equal? ((flow '(+ 1 2)) 5) '(+ 1 2) "literal quoted list")
      (check-equal? ((flow `(+ 1 ,(* 2 3))) 5) '(+ 1 6) "literal quasiquoted list")
      (check-equal? (syntax->datum ((flow #'(+ 1 2)) 5)) '(+ 1 2) "Literal syntax quoted list"))

But this doesn't work, with the error:

raco setup:   qi-lib/flow/aux-syntax.rkt:53:16: pattern: pattern keyword not allowed here
raco setup:     at: ...
raco setup:     in: (pattern #s(_ ...))

It doesn't like #s(_ ...). From the docs for the prefab syntax pattern, it looks like the pattern expects a specific prefab-struct-key (like dog) and not a generic pattern like _. So, I'm not sure if it would be possible to match arbitrary prefabs using this approach.

benknoble commented 1 year ago

LGTM. I agree that the prefab patterns require a literal prefab struct key, which kind of makes sense: mentioning a prefab by writing #s(cat "tom") is enough to create such a prefab structure type with a single field (entirely distinct from #s(cat "tom" black)—also note the implicit quoting).

Perhaps there's a way to inspect the syntax and determine if it's a prefab struct literal? I see that prefab-struct-key is #f if the argument is not a prefab instance, so perhaps some version of #:when (prefab-struct-key (syntax-e #'the-possibly-literal-expr))?

countvajhula commented 1 year ago

Great points. And that totally worked 😃 The tests are failing now due to the bindingspec name change, but that I verified locally that it works when the updated dependency name and syntax is used.