Skip to content

Commit 3416fab

Browse files
committed
Design doc updates
1 parent cbc97b7 commit 3416fab

File tree

1 file changed

+62
-39
lines changed

1 file changed

+62
-39
lines changed

clojureRS.org

Lines changed: 62 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1+
12
* Design Notes
23
** Dynamic Typing
34
Let's say we have a function like the invoke function (check out
4-
clojure.lang.IFn) for function-like types, which takes a variable
5-
number of arguments whose types are not known at compile time. In
6-
Java, this looks like
5+
clojure.lang.IFn) for function-like types, that is meant to invoked on
6+
an certain number of arguments whose types are not known at compile time.
7+
#+BEGIN_SRC clojure
8+
;; Example of a 'function like type'; {}, an IFn that is not a function that can nontheless
9+
;; be invoked on arguments
10+
({:name "Cameron"
11+
:age 100} :name) => "Cameron"
12+
#+END_SRC
713

14+
In Java, this invoke function looks something like
815
#+BEGIN_SRC java
916
public Object invoke(Object arg1,Object arg2 ...)
1017
#+END_SRC
@@ -16,16 +23,6 @@
1623
#+BEGIN_SRC rust
1724
fn invoke<'a>(arg1: &'a dyn Any, ..) -> &'a dyn Any
1825
#+END_SRC
19-
20-
(But, considering that really we want to be often returning a
21-
new value with invoke, and thus our 'reference', despite
22-
starting in the function, should be existing beyond the function
23-
itself, we'd more so probably need to return a proper pointer on
24-
the heap, perhaps a Box<dyn Any>. When I was experimenting with
25-
this approach, I ended up using a Rc<dyn Any>, which fit better
26-
with some other implementation details and was 'easier', but there
27-
was still a lot to explore there)
28-
2926
or
3027

3128
2. To have a wrapper ADT (enum) that knows all possible types ahead of time; ie, something like
@@ -41,10 +38,9 @@
4138
#+END_SRC
4239

4340
For now, I have moved forward with #2, as there appear to be some
44-
major issues one runs into with #1, although I am open to hearing
45-
from others wiser than I in Rust
46-
*** TODO Document problem with #1
47-
41+
major issues one runs into with #1, although, like with all decisions on
42+
this sheet, I am open to hearing from others wiser than I in Rust.
43+
*** TODO Document problem with #1
4844
** Exceptions
4945
How best represent exceptions?
5046
*** Conditions
@@ -59,7 +55,6 @@
5955
There's a few things to think about here, for now let's just have
6056
erroneous situations flat out return a Condition type, and start
6157
adding more behavior when we get back to this.
62-
6358
** Keeping the codebase close
6459
Originally, at least ,the goal was to keep the Rust base as similar
6560
to the Java / C# codebase as possible for consistency, but now I am
@@ -72,31 +67,59 @@
7267
the IFn trait, which for now is keeping the IFn name. See notes at
7368
top of IFn for more info
7469

70+
*** 4/14/2020 Note
71+
One glitch in my thinking that didn't really compute when I wrote this
72+
is that the, say, Java version looks pretty straightforward underneath
73+
-- if you want a hashmap, for instance, its just implemented in Java --
74+
but I am forgetting that, by virtue of the JVM, it is sort of
75+
automatically getting an efficient bytecode to evaluate to. Without
76+
that luxury, we likely do not want to just likewise implement things
77+
outright, we will likely also want to add an additional step where everything
78+
too perhaps compiles to a more efficient bytecode -- or we might
79+
implement some sort of JIT action. In the long run, I'd love for this
80+
to be like SBCL, although I imagine that might take a few decades
7581
** Explore more the idea of a clean rust FFI / interop, in the usual spirit of Clojure
7682
I get the impression that runtime reflection in Rust would be difficult if not downright
7783
impossible, so for now I would like to look into producing our interop functions at compile time
7884
(or rather, 'pre compile time'; parsing our rust files, producing the appropriate ClojureRS rust code bridging
7985
the two, and the compiling the entire project after)
8086

81-
** Clojure map comments
82-
For now, I decided to add some meta data to some of the Rust-Clojure functions as an actual map in the comment
83-
(ie,
84-
#+BEGIN_SRC rust
85-
/*
86-
{:clojure-fn "+"}
87-
*/
88-
struct AddFn {
89-
}
90-
#+END_SRC
91-
I am not 100% I have a conscious reasoning yet, but I often like
92-
expressing data just as data, this is one of the draws of Clojure
93-
for me as it is. The map here is explicit, it is human readable, but
94-
also easily reflected read and manipulated by software. And it is
95-
expressed with the same, to-the-point language you can use to
96-
express any other information.
87+
*** 4/14/2020 Note
88+
At the very least, we are closer, as we have some intermediate Rust traits and types we can use to create
89+
Rust values that can live inside ClojureRS. Perhaps the next step might be some derive macros,
90+
and then generation itself might become a lot easier, as the bulk of it would be carried out
91+
from within Rust itself
92+
** TypeTag
93+
Put in separate file as Value or same? Let's keep it separate and see how its used as the program progresses
94+
** IFn Values
95+
If we notice, our Value enum, which just wraps all potential types (this is how we're implementing dynamic typing), has some 'types' that are not concretions but interfaces. And then it has some types that are more
96+
complicated yet, like Conditions (Conditions technically are a value with a type, but are they exactly
97+
returned in the same 'expression space', or aren't they sort of returned to this separate 'exception channel',
98+
and not to the environment where it was written but to a handler anywhere higher up awaiting it)
99+
100+
Anyways, I just want to keep this in mind. Right now Value wraps *everything* in a flat sort of way,
101+
but they aren't all quite on the same 'level'.
102+
103+
** Conditions
104+
Perhaps they could look like
105+
#+BEGIN_SRC clojure
106+
(defn div [x y]
107+
(restart-case
108+
(if (not= y 0)
109+
(/ x y)
110+
;; Oh yeah this looks sexy
111+
(error :divide-by-zero {:message "Tried to divide by zero"}))
112+
(return-zero [] 0)
113+
(return-value [r] r)
114+
(div-new-vals [x y] (/ x y))
115+
(div-new-denominator [v] (/ x v))))
116+
117+
(defn test-div-error
118+
(handler-bind
119+
:on-zero-denominator
120+
(fn [cond]
121+
(println (:message cond))
122+
(invoke-restart :return-value 10))
97123

98-
Anyways, for now I am only listing the Var this function should
99-
correspond to, as all other information can be found on said Var,
100-
although if I later realize it helps to have this information on
101-
the Rust implementation of a function at a glance , I'm not against
102-
adding it there, even if its repeat information
124+
(div 5 0)))
125+
#+END_SRC

0 commit comments

Comments
 (0)