GNU Smalltalk - Break from whileTrue loop without return - loops

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".

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.

How to add a break in a trial loop in PsychoPy

I'm learning how to work with PsychoPy. My problem is that I cannot add a break in a trial loop within another loop.
Situation:
There are two stimuli lists: ListA.xlsx and ListB.xlsx. Both lists contain 20 sentences. A third list ('AB.xlsx') refers to block A ('ListA.xlsx') and block B ('ListB.xlsx').
When I start the experiment, PsychoPy runs through the twenty sentences of ListA.xlsx in a loop. After block A, the experiment stops for a break. The participant can continue the experiment by pressing the spacebar. When the experiment resumes, PsychoPy runs through the twenty sentences of ListB.xlsx in a loop.
For the block break, I'm using the following code:
if blocks.thisTrialN not in [1] :
continueRoutine=False
Problem:
What I want to add is a break within block A and within block B, i.e. I want to add a break after 10 sentences. I've already tried many different things, but I don't get it to work.
I'd appreciate any advice!
In your "break" routine, insert a code component and put something like this in its "begin routine" tab:
if currentLoop.thisN != 9: # NB counting is 0-based
continueRoutine = False
Builder maintains a variable named currentLoop to refer to whatever loop is currently running, so this code and routine can be re-used in any loop in your experiment, without needing to refer to the name of the specific loop that is enclosing it.

Eiffel separate object into ensure statement

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.

Ruby - Error accessing instance variables

I'm learning Ruby, and I'm having a problem while making a program.
I have a class "LineAnalyzer" that has 4 parameters (2 provided and 2 calculated). Both calculated params are: #high_wf_count (integer) and #high_wf_words (array).
Then, I have this one:
class Solution < LineAnalyzer
attr_reader :analyzers,
:highest_count_across_lines,
:highest_count_words_across_lines
def initialize
#analyzers = []
end
def analyze_file
File.foreach('test.txt') do |line|
#analyzers << LineAnalyzer.new(line.chomp,#analyzers.length+1)
end
end
def calculate_line_with_highest_frequency
#highest_count_words_across_lines = []
#highest_count_across_lines = #analyzers.max_by do
|a| a.instance_variable_get(:#highest_wf_count)
end .instance_variable_get(:#highest_wf_count)
#highest_count_words_across_lines << #analyzers.each do
|a| a.instance_variable_get(:#highest_wf_count) == #highest_count_across_lines
end .instance_variable_get(:#highest_wf_words)
end
end
The problem is that I cannot append the array #highest_wf_count to #highest_count_words_across_lines in the way I've done (it returns nil). But, I've previously taken the integer #highest_wf_count in the same way perfectly.
Can anyone tell me where's the problem?
Thanks in advance!
It seems that your problem is in this bit of code:
#highest_count_words_across_lines << #analyzers.each do
|a| a.instance_variable_get(:#highest_wf_count) == #highest_count_across_lines
end .instance_variable_get(:#highest_wf_words)
Preferably formatted as:
#highest_count_words_across_lines << #analyzers.each do |analyzer|
analyzer.instance_variable_get(:#highest_wf_count) == #highest_count_across_lines
end.instance_variable_get(:#highest_wf_words)
The problem here is that you are calling .instance_variable_get(:#highest_wf_words) on the result of the :each method.
A few lines above, you are doing something similar, where you call .instance_variable_get(:#highest_wf_count) on the result of the :max_by method, and it is working.
The difference between :max_by and :each is that :max_by returns a single analyzer, whereas :each returns the array of #analyzers over which it is iterating.
When you call :instance_variable_get(:#highest_wf_words) on that array, it's returning nil because an array will not have an instance variable named :#highest_wf_words
That is where your problem exists.
Sidenote:
It is generally not good practice to ever use :instance_variable_get. I would recommend adding to your analyzer class attr_reader :highest_wf_words, :highest_wf_count
Then, instead of calling analyzer.instance_variable_get(:#highest_wf_words), you can just call analyzer.highest_wf_words
There's a lot going on here and most of the code results from going against the grain when writing Ruby. Using instance_variable_get should be an absolute last resort. It's considered highly rude to just reach into an object and pull out a variable. It creates ugly and undesirable inter-dependencies. If that other object wanted to give you that value it would have a method to access it.
The way I see it what you're trying to do boils down to something like this:
def highest_frequency
#analyzers.map do |a|
a.highest_wf_count
end.sort.last
end
Let Analyzer implement highest_wf_count as a method, even if it's just an attr_reader. This gives you the flexibility to change how and when that value is computed. Maybe you don't need to do it when the object is initialized. Maybe it's done in another thread, or it's evaluated lazily.
Whenever possible try and structure your code as a series of straight-forward transformations. Try not to create convoluted, branching, ugly comparisons. Lean on Enumerable whenever possible, it's usually got a method that does exactly what you want, or two that in conjunction do the job perfectly.
This is way more complex than it needs to be (or should be).
Why does Solution subclass LineAnalyzer? And why are you using instance_variable_get? You should define getter methods using attr_reader on the LineAnalyzer class so you can call methods instead of using instance_variable_get, which is a brute force approach that should only be used as a last resort.
I think you should fix this before proceeding.
When you have instance methods created with attr_reader, calculating the max becomes very simple:
highest_count_across_lines = #analyzers.map(&:highest_wf_count).max
I think your error probably is caused by these lines:
#highest_count_words_across_lines << #analyzers.each do
|a| a.instance_variable_get(:#highest_wf_count) == #highest_count_across_lines
end .instance_variable_get(:#highest_wf_words)
I suggest simplifying this code, and the error will probably present itself to you. Did you really mean to append the value returned by each to #highest_count_words_across_lines? This will be an Array of analyzers. The Array class, of course, does not have a variable named :#highest_wf_words.
Again, I think you really need to simplify this code.

How do I make an iterator over a 2-dimensional table in Lua?

I've got a lua table made of tables, so it's two-dimensional: root -> child -> grandchild.
None of the levels of this hierarchy is guaranteed to be "array-like". The first level has integers with "nil gaps", and second one is not even indexed by integers (but by tables).
The table in question is a private structure inside a lib. I want to provide a way for the library user to parse its grandchildren. I don't care much about the order in which the they are parsed, as long as all of them are.
The first thing I thought about was using a function accepting a callback:
-- this scope has access to root
function eachGrandChild(callback)
for _,child in pairs(root) do
for index,grandChild in pairs(child)
callback(index, grandChild)
end
end
end
Usage:
-- no access to root, only to eachGrandChild
eachGrandChild(function(index, grandChild) print(index, grandChild) end)
This much is understood.
My question is: could I provide a similar functionality using an iterator instead?
I'm talking about something that would allow me to do this:
for index,grandChild in iterator() do
print(index, grandChild)
end
I've been thinking about this for a while but I'm not able to crack it. All the examples I've seen use numbers to easily "manage the state of the iterator" on each iteration. Since I don't have numbers, I'm a bit stuck.
Coroutines make it easy to write this kind of iterator. A coroutine is a function whose execution can be suspended and resumed, conceptually like a thread. A coroutine can contain deeply nested loops, yield a value from the inner most loop, then continue right where it left off when resumed. When it yields, the caller who resumed it can receive yielded values.
In your case, convert eachGrandChild into a generator function which yields grandchildren.
function eachGrandChild(root)
for _,child in pairs(root) do
for index,grandChild in pairs(child) do
coroutine.yield(index, grandChild)
end
end
end
Then use coroutine.wrap to create a function that will create a coroutine for your generator and resume it each time the function is called.
function grandChildren(t)
return coroutine.wrap(function() eachGrandChild(t) end)
end
Now you have your iterator:
for key, val in grandChildren(root) do
print(key, val)
end
There's a chapter on this in Programming in Lua.
I agree with Mud that coroutines are the best approach to the problem.
For the record, I have written an iterator without coroutines for the sake of comparison.
The first function eachGrandChild is called for each element. It uses a state variable, the containing the two indices (the top and second level).
function eachGrandChild(state)
while state.childIndex ~= nil do
local child = root[state.childIndex]
state.grandChildIndex = next(child, state.grandChildIndex)
if state.grandChildIndex == nil then
state.childIndex = next(root, state.childIndex)
else
return state.grandChildIndex, child[state.grandChildIndex]
end
end
end
The iterator is initialized with the helper function:
function grandChildren(root)
return eachGrandChild, {childIndex = next(root)}
end
Now the iterator can be used normally:
for key, val in grandChildren(root) do
print(key, val)
end
Compared to the coroutine based version, eachGrandChild has more lines of code and is more difficult to read.

Resources