How does functions of Red/Rebol pass parameters, by value or by reference? - rebol

I'm puzzled by the result of the following two codes:
Code1:
>> f: func [x][head insert x 1]
== func [x][head insert x 1]
>> a: [2 3]
== [2 3]
>> f a
== [1 2 3]
>> a
== [1 2 3] ;; variable a is destroyed
Code2:
>> g: func [x y][x: x + y]
== func [x y][x: x + y]
>> c: 1 d: 2
== 2
>> g c d
== 3
>> c
== 1
>> d
== 2
;;variable c and d keep their original values
My question is: how does functions in Red/Rebol get their arguments, by value or by reference?

That's a good question. And the answer is: parameters are passed by value, but some parameters may contain references within them.
Every value in Rebol/Red is represented as a boxed structure of uniform size, often called a slot or a cell. This structure is logically divided into 3 parts: header, payload and extra.
┌─────────┐
│ header │
├─────────┤ Historically, the size of the value slot is 4 machine pointers in size,
│ payload │ 1 for header, 1 for extra, and 2 for payload.
│ │ E.g. on 32-bit systems that's 128 bits, or 16 bytes.
├─────────┤
│ extra │
└─────────┘
The header contains various meta-information that helps to identify the value that payload contains, the most important piece is a type tag, or, in Rebol's parlance, a datatype ID.
The payload contains the data representation of some value, such as numbers, strings, characters, etc.
The extra part serves as a space reserved for optimizations (e.g. a cache) and stashing data that doesn't fit into the payload.
Now, value slots have uniform size, and, naturally, some data simply cannot fit in them fully. To address that, value slots can contain references (basically a pointer with an extra layer of indirection, to make data garbage-collectible and shareable between multiple slots) to external buffers.
┌─────────┐
│ header │
├─────────┤
│ payload │ --→ [buffer]
│ │
├─────────┤
│ extra │
└─────────┘
Values that fit into the value slot (such as scalar!) are called direct, and values that don't (such as series!) are called indirect: because references within them introduce a level of indirection between the value slot and the actual data. For example, here is how various slot layouts are defined in Red.
Content of the value slot is simply a bunch of bytes; how they are interpreted by the runtime depends on the datatype ID in the header. Some bytes might be just literals, and others might be indirect pointers to data buffers. Passing parameters to a function just copies these bytes, regardless of what they mean. So, both literals and references are treated the same in this regard.
So, if you have a value slot that internally looks like this:
┌────────┐
│DEADBEEF│ header
├────────┤
│00000000│ payload
│FACEFEED│
├────────┤
│CAFEBABE│ extra
└────────┘
Then, say, FACEFEED can be a signed integer -87097619, or varied-size bit-fields packed together, or it can be a machine pointer: that depends on what datatype ID in the header (e.g. EF byte) ascribes to it.
When value slot is passed as a parameter to a function, all of its bytes will simply be copied over onto the evaluation stack, regardless of what they encode or represent. For direct values the logic is straightforward: if the parameter is modified within the function, the original value is left untouched, because it's just a copy. That's what your 2nd example is all about.
Parameter Stack
┌────────┐ ┌────────┐
│DEADBEEF│ │DEADBEEF│
├────────┤ ├────────┤
│00000000│ │00000000│ Both represent the same integer -87097619.
│FACEFEED│ │FACEFEED│ ← You modify this one, with no effect on the other.
├────────┤ ├────────┤
│CAFEBABE│ │CAFEBABE│
└────────┘ └────────┘
But with indirect values it's more interesting. They are copied over verbatim too, but that makes two copies share the same references to a single buffer (remember that bytes representing reference are the same in both slots). So, when you modify a buffer via one (e.g. insert element at the head), the other reflects the change too.
Parameter Stack
┌────────┐ ┌────────┐
│DEADBEEF│ │DEADBEEF│
├────────┤ ├────────┤
│00000000│ │00000000│ Both refer to the same buffer (same machine pointers!)
│FACEFEED│──┐───│FACEFEED│
├────────┤ │ ├────────┤
│CAFEBABE│ │ │CAFEBABE│
└────────┘ │ └────────┘
↓
[b u f f e r] ← You modify the content of the buffer.
Returning to your 1st example:
>> f: func [x][head insert x 1]
== func [x][head insert x 1]
>> a: [2 3]
== [2 3]
>> f a
== [1 2 3]
>> a
== [1 2 3] ;; variable a is destroyed
Simplifying quite a bit, this is how it looks like under the hood:
value slot buffer value slot (parameter on stack)
<word a in global context> --→ [1 2 3] ←-- <word x in function's context>
Naturally, there are ways to clone value slot and a buffer to which it refers: this is what copy does.
>> f: func [x][head insert x 1]
== func [x][head insert x 1]
>> a: [2 3]
== [2 3]
>> f copy a
== [1 2 3]
>> a
== [2 3]
Diagrammatically (again, simplifying quite a bit):
value slot buffer
<x> --→ [1 2 3]
<a> --→ [2 3]
Series values (such as blocks) also contain another piece of data in their payload: an index.
>> at [a b c d] 3 ; index 3, buffer → [a b c d]
== [c d]
When passing block as a parameter, its index is copied over too, but unlike data buffer, it is not shared between the two value slots.
Parameter Stack
┌────────┐ ┌────────┐
│DEADBEEF│ │DEADBEEF│
├────────┤ ├────────┤
│00000000│ │00000000│ Suppose that 0's here are an index.
│FACEFEED│──┐───│FACEFEED│ Modifying this one won't affect the other.
├────────┤ │ ├────────┤
│CAFEBABE│ │ │CAFEBABE│
└────────┘ │ └────────┘
↓
[b u f f e r]
So:
>> foo: func [x][x: tail x] ; tail puts index, well, at the tail
== func [x][x: tail x]
>> y: [a b c]
== [a b c]
>> foo y
== [] ; x is modified
>> y
== [a b c] ; y stays the same

Related

Julia InexactError: Int64

I am new to Julia. Got this InexactError . To mention that I have tried to convert to float beforehand and it did not work, maybe I am doing something wrong.
column = df[:, i]
max = maximum(column)
min = minimum(column)
scaled_column = (column .- min)/max # This is the error, I think
df[:, i] = scaled_column
julia> VERSION
v"1.4.2"
Hard to give a sure answer without a minimal working example of the problem, but in general an InexactError happens when you try to convert a value to an exact type (like integer types, but unlike floating-point types) in which the original value cannot be exactly represented. For example:
julia> convert(Int, 1.0)
1
julia> convert(Int, 1.5)
ERROR: InexactError: Int64(1.5)
Other programming languages arbitrarily chose some way of rounding here (often truncation but sometimes rounding to nearest). Julia doesn't guess and requires you to be explicit. If you want to round, truncate, take a ceiling, etc. you can:
julia> floor(Int, 1.5)
1
julia> round(Int, 1.5)
2
julia> ceil(Int, 1.5)
2
Back to your problem: you're not calling convert anywhere, so why are you getting a conversion error? There are various situations where Julia will automatically call convert for you, typically when you try to assign a value to a typed location. For example, if you have an array of Ints and you assign a floating point value into it, it will be converted automatically:
julia> v = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> v[2] = 4.0
4.0
julia> v
3-element Array{Int64,1}:
1
4
3
julia> v[2] = 4.5
ERROR: InexactError: Int64(4.5)
So that's likely what's happening to you: you get non-integer values by doing (column .- min)/max and then you try to assign it into an integer location and you get the error.
As a side note you can use transform! to achieve what you want like this:
transform!(df, i => (x -> (x .- minimum(x)) ./ maximum(x)) => i)
and this operation will replace the column.

How to make a union of two SetHashes in Perl 6?

Given two SetHashes, one or both of them can be empty. I want to add all the elements of the second SetHash to the first one.
Since the output of the union operator is a Set, the only (and supposedly not the best one) way I managed to do it is the following.
my SetHash $s1 = <a b c>.SetHash;
my SetHash $s2 = <c d e>.SetHash;
$s1 = ($s1 (|) $s2).SetHash; # SetHash(a b c d e)
UPD: Probably this is more simple, but having to convert to .keys makes me uncomfortable.
$s1{ $s2.keys } X= True; # SetHash(a b c d e)
I'm hoping Elizabeth Mattijsen will read over your question and our answers and either comment or provide her own answer. In the meantime here's my best shot:
my %s1 is SetHash = <a b c> ;
my %s2 is SetHash = <c d e> ;
%s1 = |%s1, |%s2 ; # SetHash(a b c d e)
Elizabeth implemented the is Set (and cousins ) capability for variables declared with the % sigil (i.e. variables that declare their primary nature to be Associative) in the Rakudo 2017.11 compiler release.
Prefix |, used within an expression that's an argument list, "flattens" its single argument if said single argument is composite (the relevant doc claims it must be a Capture, Pair, List, Map, or Hash):
say [ [1,2], [3,4]]; # [[1 2] [3 4]]
say [|[1,2], [3,4]]; # [1 2 [3 4]]
say [|1, 2, [3,4]]; # [1 2 [3 4]]

Destructuring a list with equations in maxima

Say that I have the following list of equations:
list: [x=1, y=2, z=3];
I use this pattern often to have multiple return values from a function. Kind of of like how you would use an object, in for example, javascript. However, in javascript, I can do things like this. Say that myFunction() returns the object {x:1, y:2, z:3}, then I can destructure it with this syntax:
let {x,y,z} = myFunction();
And now x,y,z are assigned the values 1,2,3 in the current scope.
Is there anything like this in maxima? Now I use this:
x: subst(list, x);
y: subst(list, y);
z: subst(list, z);
How about this. Let l be a list of equations of the form somesymbol = somevalue. I think all you need is:
map (lhs, l) :: map (rhs, l);
Here map(lhs, l) yields the list of symbols, and map(rhs, l) yields the list of values. The operator :: means evaluate the left-hand side and assign the right-hand side to it. When the left-hand side is a list, then Maxima assigns each value on the right-hand side to the corresponding element on the left.
E.g.:
(%i1) l : [a = 12, b = 34, d = 56] $
(%i2) map (lhs, l) :: map (rhs, l);
(%o2) [12, 34, 56]
(%i3) values;
(%o3) [l, a, b, d]
(%i4) a;
(%o4) 12
(%i5) b;
(%o5) 34
(%i6) d;
(%o6) 56
You can probably achieve it and write a function that could be called as f(['x, 'y, 'z], list); but you will have to be able to make some assignments between symbols and values. This could be done by writing a tiny ad hoc Lisp function being:
(defun $assign (symb val) (set symb val))
You can see how it works (as a first test) by first typing (form within Maxima):
:lisp (defun $assign (symb val) (set symb val))
Then, use it as: assign('x, 42) which should assign the value 42 to the Maxima variable x.
If you want to go with that idea, you should write a tiny Lisp file in your ~/.maxima directory (this is a directory where you can put your most used functions); call it for instance myfuncs.lisp and put the function above (without the :lisp prefix); then edit (in the very same directory) your maxima-init.mac file, which is read at startup and add the two following things:
add a line containing load("myfuncs.lisp"); before the following part;
define your own Maxima function (in plain Maxima syntax with no need to care about Lisp). Your function should contain some kind of loop for performing all assignments; now you could use the assign(symbol, value) function for each variable.
Your function could be something like:
f(vars, l) := for i:1 thru length(l) do assign(vars[i], l[i]) $
which merely assign each value from the second argument to the corresponding symbol in the first argument.
Thus, f(['x, 'y], [1, 2]) will perform the expected assigments; of course you can start from that for doing more precisely what you need.

What's the difference between `a: [b 1]` and `a: [b: 1]`, in red?

What is the difference between
a: [b 1]
; and
a: [b: 1]
both give the same results for
> a/b
1
they differ for a/1 though.
When do you use what? And the 2nd is a set, what is the 1st?
the 2nd is a set, what is the 1st?
You can get answers by looking at the type:
>> type? first [b 1]
== word!
>> type? first [b: 1]
== set-word!
What is the difference
When you use the expression a/b you are writing something that acts like a SELECT statement, looking up "any word type" matching b in the block indicated by a, then returning the item after it in the block.
Red follows heritage from Rebol--defaulting path selections to be the "non-strict" form of SELECT, which uses a "non-strict" form of equality
>> (first [a:]) = (first [a]) ;-- default comparison
true
>> select [b 1] (quote b)
== 1
>> select [b: 1] (quote b)
== 1
To get the strict behavior of telling the difference, you need to use the /CASE refinement (in the sense of "case-sensitive"):
>> (first [a:]) == (first [a]) ;-- strict comparison
true
>> select/case [b: 1] (quote b)
== none
>> select/case [b: 1] (quote b:)
== 1
Red seems to be at least a little more consistent about this than R3-Alpha, for instance honoring the equality of 1% and 0.01:
>> 1% = 0.01
== true ;-- both R3-Alpha and Red
>> select [0.01 "test"] 1%
== "test" ;-- in Red
>> select [0.01 "test"] 1%
== none ;-- in R3-Alpha
But it shows that there's a somewhat dodgy history behind equality semantics.
When do you use what?
Good question. :-/ Notation-wise in your source, you should use that which you feel most naturally fits what you want to express. If you think a SET-WORD! is appropriate then use it, otherwise use a WORD!. Implementation-wise, there are some nuances that are beyond the scope of a simple answer (locals gathering in FUNCTION, for instance). If you know something will ultimately need to be transformed into an assignment, it may be helpful to use SET-WORDs.
Path evaluation is sketchy, in my opinion. It arose as a syntactic convenience, but then produced a cross product of behaviors for every type being selected from every other type. And that's to say nothing of the variance in how functions work (what would x: :append/dup/only/10/a mean?)
Small example: PATH! behavior in Rebol used a heuristic where if you are evaluating a path it will act as a PICK if the path component is an integer:
>> numbers: [3 2 1]
>> pick numbers 3
== 1 ;-- because the 3rd element is a 1
>> select numbers 3
== 2 ;-- because 2 comes after finding a 3
>> numbers/3
== 1 ;-- acts like PICK because (...)/3 uses an INTEGER!
...but as above, it will act like a SELECT (non-strict) if the thing being chosen is a WORD!:
>> words: [a b c]
>> select words 'a
== b ;-- because b is the thing after a in the block
>> pick words 'a
;-- In Rebol this is an error, Red gives NONE at the moment
>> words/a
== b ;-- acts like SELECT because (...)/a uses a WORD!
So the difference between SELECT and PICK accounts for that difference you're seeing.
It gets weirder for other types. Paths are definitely quirky, and could use a grand unifying theory of some sort.
And the 2nd is a set, what is the 1st?
It seems you are looking at both [b 1] and [b: 1] as code, but they are actually just data. More precisely, they are lists of two elements: a word! or set-word! value followed by an integer! value.
a/b is a syntactic sugar for select a 'b, which retrieves the value following 'b word (using a find call internally). For convenience, the searching for 'b also matches other word types:
red>> find [:b] 'b
== [:b]
red>> find [/b] 'b
== [/b]
red>> find ['b] 'b
== ['b]
red>> find [b] 'b
== [b]
As a side note, remember that a lit-word will evaluate to a word, which is sometimes referred by the "word-decaying" rule:
red>> 'b
== b
/case refinement for find and select will apply a stricter matching, ensuring that the types are also the same. Though, you obviously cannot use it with path notation, you would need to replace the path with a select/case call instead.
So, both are giving the same result for a/b, because both will return the value following b word (regardless of his "word sub-type"):
red>> [b 1] = [b: 1] ;-- loose comparison, used by `find` and `select`.
== true
red>> [b 1] == [b: 1] ;-- strict comparison, used by `find/case` and `select/case`.
== false
they differ for a/1 though.
Integer values have specific semantics in paths. They act as sugar for pick, so a/1 is equivalent to pick a 1. You can also force that behavior other words referring to integers in paths, by making them get-word! values:
red>> c: 1
== 1
red>> a: [b 123]
== [b 1]
red>> a/:c
== b
red>> a: [b: 123]
== [b: 123]
red>> a/:c
== b:
red>> c: 2
== 2
red>> a/:c
== 123
Read more about paths from Rebol Core Manual: http://www.rebol.com/docs/core23/rebolcore-16.html#section-2.10
When do you use what?
For a/b vs a/1 usage, it depends if you want to achieve a select or a pick operation.
For [b 1] vs [b: 1], it depends on the later use of the block. For example, if you are constructing a block for serving as an object or map specification, then the set-word form is a better fit:
red>> a: [b:]
== [b:]
red>> append a 123
== [b: 123]
red>> c: object a
== make object! [
b: 123
]
Also, you should use the set-word form each time you imply a "key/value" relationship, it makes your intent clearer for yourself and other readers as well.

Clojure - sequence of objects

I have a Clojure function:
(def obseq
(fn []
(let [a 0
b 1
c 2]
(println (seq '(a b c))))))
It outputs :
(a b c)
I want it to output a sequence containing the values of a, b, and c, not their names.
Desired output:
(1 2 3)
How do I implement this?
Short answer:
clj.core=> (defn obseq []
(let [a 0
b 1
c 2]
(println [a b c])))
#'clj.core/obseq
clj.core=> (obseq)
[0 1 2]
nil
Long answer:
Quoting a form like '(a b c) recursively prevents any evaluation inside the quoted form. So, the values for your 3 symbols a, b, and c aren't substituted. It is much easier to use a vector (square brackets), which never needs to be quoted (unlike a list). Since the vector is unquoted, the 3 symbols are evaluated and replaced by their values.
If you wanted it to stay a list for some reason, the easiest way is to type:
clj.core=> (defn obseq [] (let [a 0 b 1 c 2] (println (list a b c))))
#'clj.core/obseq
clj.core=> (obseq)
(0 1 2)
nil
This version also has no quoting, so the 3 symbols are replaced with their values. Then the function (list ...) puts them into a list data structure.
Note that I also converted your (def obseq (fn [] ...)) into the preferred form (defn obseq [] ...), which has the identical result but is shorter and (usually) clearer.