Eiffel separate object into ensure statement - eiffel

Is there a way to have a separate object to be checked as ensure with the separate obj as l_obj statement?
I guess having a boolean function should work.
Any reason for that I don't understand?
set_position (a_pos: like position)
do
position := a_pos
separate status_keeper as l_status_keeper_sep do
l_status_keeper_sep.set_position (position)
end
ensure
position = a_pos
separate status_keeper as l_status_keeper_sep do -- the compiler doesn't agree with separate keyword here
l_status_keeper_sep.position = a_pos
end
end

At the moment there is no "separate expression" similar to "separate instruction". And, as you mention, separate instructions are not allowed in the context where only a boolean expression is expected, in postconditions in particular.
Even if there were such a construct, it would not work. The separate object could change its state between two subsequent separate instructions. For example, the following code is wrong:
separate foo as x do
x.put (something) -- Set `foo.item` to `something`.
end
separate foo as x do
check
item_is_known: x.item = something
end
end
The check instruction could easily lead to assertion violation in the following execution scenario:
The first separate instruction is executed.
Some other processor makes a call to foo.put.
The check instruction compares something to the value set in step 2.
If the code has to ensure some property of a separate object, it should be enclosed in a routine body, and the separate object should be passed as an argument:
set_position (value: like position; keeper: like status_keeper)
do
position := value
keeper.set_position (value)
ensure
position = value
keeper.position = value
end
Separate instructions were invented only to avoid writing single-line wrappers just to make a call on a separate object. Anything else is better using the original SCOOP approach with full-fledged features with separate arguments.

Related

How to idiomatically support closing values with pairs()?

I'm new to Lua (language version 5.4 if it matters, there doesn't seem to be a tag for that version on SO yet) and I'm trying to find the most idiomatic way to implement iteration (for loop) over a userdata object.
The Lua 5.4 Reference Manual says regarding a loop statement for var_1, ยทยทยท, var_n in explist do body end:
The loop starts by evaluating explist to produce four values: an iterator function, a state, an initial value for the control variable, and a closing value.
The idiomatic way to loop seems to be using the pairs(t) function. This also works for userdata via the __pairs metamethod. However:
If t has a metamethod __pairs, calls it with t as argument and returns the first three results from the call.
Why only three instead of four? If I have a complex userdata object that needs to allocate some resource for a loop, I'll need that closing value so I know when to deallocate that resource in case the loop ends early, right? Does that mean I cannot use pairs in such a case or am I missing something?
I could of course provide a new function, say pairs4, but that doesn't seem to be very idiomatic.
Because that's how it has always worked since at least Lua 5.0. pairs always returned 3 values because for previously only took 3 values.
"to-be-closed variables" are a new feature of Lua 5.4, as is the fourth value for generic for. Why pairs wasn't updated to match is unknown. It is possible that pairs returns all of the values from the __pairs metamethod, but I haven't looked at the implementation to verify this.
In this case, I would suggest writing a pairs_close that returns 4 arguments from the __pairs metamethod.

GNU Smalltalk - Break from whileTrue loop without return

What is a simple and concise way to break from a whileTrue loop in GNU Smalltalk that doesn't require returning?
Here is my code. I want to break from the loop at Line 31 at the end if char_stack is empty.
https://gist.github.com/SYZYGY-DEV333/ea3f5eeb3473927c8faa294bb72a8858
Any help would be much appreciated.
One of the articles of the Byte magazine (1982) titled Building Control Structures in the Smalltalk-80 System by Peter Deutsch , shows how easy is to implement while-loop breaks for infrequent events that might happen inside the loop.
To implement this we only need a new class and an extension to BlockClosure, making a total of 9 lines of code(!).
The class: BlockWithExit, subclass of Object with two ivars exit and block and the following methods
on: aBlock
block := aBlock
value
exit := [^nil].
^block value
exit
exit value
Extension
BlockClosure>>withExit
^BlockWithExit new on: self
and that's it!
Example
Find the max of a collection until its exhaustion or until nil is found (the infrequent event)
maxBeforeNil: aCollection
| max supplier loop |
max := 0.
supplier := aCollection readStream.
loop := [
[supplier atEnd]
whileFalse: [
value := supplier next.
value isNil ifTrue: [loop exit].
max := max max: value]] withExit.
loop value.
^max
Why does this work the way it does? Because a block with a non-local return exits from the method that defines the block.
In this case this method is BlockWithExit>>value, therefore when [^nil] is evaluated from loop exit, the flow exits value and goes to its sender, right after loop value.
The outstanding corollary of Deutsch's discovery is that the whole mechanism of Exceptions can be built using this very same trick of defining an exit block in an ivar like: exit := [^nil].
In general, Smalltalk does not have a way of breaking from a loop, except for returning from the enclosing method.
Try to extract your loop into another method from which you can return to break from the loop.
In a way, Smalltalk the language does not even have loops... but some methods happen to evaluate blocks more than once. Hence it does not have a special way to terminate "loops". Return is the way.
If you have not already done so, familiarize yourself with the different iteration methods of Collection: do:, select:, collect:, detect:ifNone:, ... The latter is another way to run an "incomplete" loop over a collection, but it does not solve all cases in which you might wish for a "break".

Common Lisp Binding in Loop Macro

I want to rebind a special variable inside of a loop. Now, normally, this is accomplished using a let.
(let ((*read-eval* nil))
(do-something-here))
But since the loop macro has these nice with clauses, I thought I might be able to do so in there. The expression (macroexpand '(loop with *read-eval* = nil)) ends up expanding the binding to a let, so it will definitely work on my implementation specifically. But I can't find anything in the standard indicating that this is standardized behavior. So, I suppose, my question is this:
(loop with *read-eval* = nil
for i from 1 to 10
do (something-involving-the-read-function))
Are conforming implementations required to modify the existing *read-eval* variable, or is there a risk that they might create a new lexical variable of the same name?
*read-eval* is a global special variable. There is no way to undo that, i.e., create a local lexical binding for it.
with clause is described as using bindings (as opposed to mere setting) which means that, indeed, once the loop is done, we'll be back to the original value (to answer #joshua-tailor's question).
Let us think rationally. (loop with foo = nil ...) definitely does establish a binding for foo. So, for (loop with *read-eval* = nil ...) not to establish that binding, the implementation has to check (at macroexpansion or compile time) whether *read-eval* will be a dynamic variable at run time. This sounds insane.

eval in function scope (accessing function args)

Given:
abstract ABSGene
type NuGene <: Genetic.ABSGene
fqnn::ANN
dcqnn::ANN
score::Float32
end
function mutate_copy{T<:ABSGene}(gene::T)
all_fields_except_score = filter(x->x != :score, names(T))
all_fields_except_score = map(x->("mutate_copy(gene.$x)"),all_fields_except_score)
eval(parse("$(T)("*join(all_fields_except_score,",")*")"))
end
ng = NuGene()
mutated_ng = mutate_copy(ng)
results in:
ERROR: gene not defined
in mutate_copy at none:4
If I just look at it as a string (prior to running parse and eval) it looks fine:
"NuGene(mutate_copy(gene.fqnn),mutate_copy(gene.dcqnn))"
However, eval doesn't seem to know about gene that has been passed into the mutate_copy function.
How do I access the gene argument that's been passed into the mutate copy?
I tried this:
function mutate_copy{T<:ABSGene}(gene::T)
all_fields_except_score = filter(x->x != :score, names(T))
all_fields_except_score = map(x-> ("mutate_copy($gene.$x)"),all_fields_except_score)
eval(parse("$(T)("*join(all_fields_except_score,",")*")"))
end
But that expands the gene in the string which is not what I want.
Don't use eval! In almost all cases, unless you really know what you're doing, you shouldn't be using eval. And in this case, eval simply won't work because it operates in the global (or module) scope and doesn't have access to the variables local to the function (like the argument gene).
While the code you posted isn't quite enough for a minimal working example, I can take a few guesses as to what you want to do here.
Instead of map(x->("mutate_copy(gene.$x)"),all_fields_except_score), you can dynamically look up the field name:
map(x->mutate_copy(gene.(x)), all_fields_except_score)
This is a special syntax that may eventually be replaced by getfield(gene, x). Either one will work right now, though.
And then instead of eval(parse("$(T)("*join(all_fields_except_score,",")*")")), call T directly and "splat" the field values:
T(all_fields_except_score...)
I think the field order should be stable through all those transforms, but it looks a pretty fragile (you're depending on the score being the last field, and all constructors to have their arguments in the same order as their fields). It looks like you're trying to perform a deepcopy sort of operation, but leaving the score field uninitialized. You could alternatively use Base's deepcopy and then recursively set the scores to zero.

Using C variable inside Lua alongside nested functions

This is a sort of followup to my previous question about nested registered C functions found here:
Trying to call a function in Lua with nested tables
The previous question gave me the answer to adding a nested function like this:
dog.beagle.fetch()
I also would like to have variables at that level like:
dog.beagle.name
dog.beagle.microchipID
I want this string and number to be allocated in C and accessible by Lua. So, in C code, the variables might be defined as:
int microchipIDNumber;
char dogname[500];
The C variables need to be updated by assignments in Lua and its value needs to be retrieved by Lua when it is on the right of the equal sign. I have tried the __index and __newindex metamethod concept but everything I try seems to break down when I have 2 dots in the Lua path to the variable. I know I am probably making it more complicated with the 2 dots, but it makes the organization much easier to read in the Lua code. I also need to get an event for the assignment because I need to spin up some hardware when the microchipIDNumber value changes. I assume I can do this through the __newindex while I am setting the value.
Any ideas on how you would code the metatables and methods to accomplish the nesting? Could it be because my previous function declarations are confusing Lua?
The colon operator (:) in Lua is used only for functions. Consider the following example:
meta = {}
meta["__index"] = function(n,m) print(n) print(m) return m end
object = {}
setmetatable(object,meta)
print(object.foo)
The index function will simply print the two arguments it is passed and return the second one (which we will also print, because just doing object.foo is a syntax error). The output is going to be table: 0x153e6d0 foo foo with new lines. So __index gets the object in which we're looking up the variable and it's name. Now, if we replace object.foo with object:foo we get this:
input:5: function arguments expected near ')'
This is the because : in object:foo is syntactic sugar for object.foo(object), so Lua expects that you will provide arguments for a function call. If we did provide arguments (object:foo("bar")) we get this:
table: 0x222b3b0
foo
input:5: attempt to call method 'foo' (a string value)
So our __index function still gets called, but it is not passed the argument - Lua simply attemps to call the return value. So don't use : for members.
With that out of the way, let's look at how you can sync variables between Lua and C. This is actually quite involved and there are different ways to do it. One solution would be to use a combination of __index and __newindex. If you have a beagle structure in C, I'd recommend making these C functions and pushing them into the metatable of a Lua table as C-closures with a pointer to your C struct as an upvalue. Look at this for some info on lua_pushcclosure and this on closures in Lua in general.
If you don't have a single structure you can reference, it gets a lot more complicated, since you'll have to somehow store pairs variableName-variableLocation on the C side and know what type each is. You could maintain such a list in the actual Lua table, so dog.beagle would be a map of variable name to one or two something's. There a couple of options for this 'something'. First - one light user data (ie - a C pointer), but then you'll have the issue of figuring out what that is pointing to, so that you know what Lua type to push in for __index and what to pop out for __newindex . The other option is to push two functions/closures. You can make a C function for each type you'll have to handle (number, string, table, etc) and push the appropriate one for each variable, or make a uber-closure that takes a parameter what type it's being given and then just vary the up-values you push it with. In this case the __index and __newindex functions will simply lookup the appropriate function for a given variable name and call it, so it would be probably easiest to implement it in Lua.
In the case of two functions your dog.beagle might look something like this (not actual Lua syntax):
dog.beagle = {
__metatable = {
__index = function(table,key)
local getFunc = rawget(table,key).get
return getFunc(table,key)
end
__newindex = function(table,key,value)
local setFunc = rawget(table,key).set
setFunc(table,key,value)
end
}
"color" = {
"set" = *C function for setting color or closure with an upvalue to tell it's given a color*,
"get" = *C function for getting color or closure with an upvalue to tell it to return a color*
}
}
Notes about the above: 1.Don't set an object's __metatable field directly - it's used to hide the real metatable. Use setmetatable(object,metatable). 2. Notice the usage of rawget. We need it because otherwise trying to get a field of the object from within __index would be an infinite recursion. 3. You'll have to do a bit more error checking in the event rawget(table,key) returns nil, or if what it returns does not have get/set members.

Resources