I am trying to compare two strings in Smalltalk, but I seem to be doing something wrong.
I keep getting this error:
Unhandled Exception: Non-boolean receiver. Proceed for truth.
stringOne := 'hello'.
stringTwo := 'hello'.
myNumber := 10.
[stringOne = stringTwo ] ifTrue:[
myNumber := 20].
Any idea what I'm doing wrong?
Try
stringOne = stringTwo
ifTrue: [myNumber := 20]`
I don't think you need square brackets in the first line
Found great explanation. Whole thing is here
In Smalltalk, booleans (ie, True or False) are objects: specifically, they're instantiations of the abstract base class Boolean, or rather of its two subclasses True and False. So every boolean has type True or False, and no actual member data. Bool has two virtual functions, ifTrue: and ifFalse:, which take as their argument a block of code. Both True and False override these functions; True's version of ifTrue: calls the code it's passed, and False's version does nothing (and vice-versa for ifFalse:). Here's an example:
a < b
ifTrue: [^'a is less than b']
ifFalse: [^'a is greater than or equal to b']
Those things in square brackets are essentially anonymous functions, by the way. Except they're objects, because everything is an object in Smalltalk. Now, what's happening there is that we call a's "<" method, with argument b; this returns a boolean. We call its ifTrue: and ifFalse: methods, passing as arguments the code we want executed in either case. The effect is the same as that of the Ruby code
if a < b then
puts "a is less than b"
else
puts "a is greater than or equal to b"
end
As others have said, it will work the way you want if you get rid of the first set of square brackets.
But to explain the problem you were running into better:
[stringOne = stringTwo ] ifTrue:[myNumber := 20]
is passing the message ifTrue: to a block, and blocks do not understand that method, only boolean objects do.
If you first evaluate the block, it will evaluate to a true object, which will then know how to respond:
[stringOne = stringTwo] value ifTrue:[myNumber := 20]
Or what you should really do, as others have pointed out:
stringOne = stringTwo ifTrue:[myNumber := 20]
both of which evaluates stringOne = stringTwo to true before sending ifTrue:[...] to it.
[stringOne = stringTwo] is a block, not a boolean. When the block is invoked, perhaps it will result in a boolean. But you are not invoking the block here. Instead, you are merely causing the block to be the receiver of ifTrue.
Instead, try:
(stringOne = stringTwo) ifTrue: [
myNumber := 20 ].
Should you be blocking the comparison? I would have thought that:
( stringOne = stringTwo ) ifTrue: [ myNumber := 20 ]
would be enough.
but I seem to be doing something wrong
Given that you are using VisualWorks your install should include a doc folder.
Look at the AppDevGuide.pdf - it has a lot of information about programming with VisualWorks and more to the point it has a lot of introductory information about Smalltalk programming.
Look through the Contents table at the beginning, until Chapter 7 "Control Structures", click "Branching" or "Conditional Tests" and you'll be taken to the appropriate section in the pdf that tells you all about Smalltalk if-then-else and gives examples that would have helped you see what you were doing wrong.
I would like to add the following 50Cent:
as blocks are actually lambdas which can be passed around, another good example would be the following method:
do:aBlock ifCondition:aCondition
... some more code ...
aCondition value ifTrue: aBlock.
... some more code ...
aBlock value
...
so the argument to ifTrue:/ifFalse: can actually come from someone else. This kind of passed-in conditions is often useful in "..ifAbsent:" or "..onError:" kind of methods.
(originally meant as a comment, but I could not get the code example to be unformatted)
Related
In an Autohotkey script, once a user presses the CapsLock key, a SplashText should pop up indicating that it is ON, or out when it is OFF, the problem here is not about the code that gets it to work but how much simpler it can get.
There are different ways that do it, some need about 25 lines, some use SetTimer and GetKeyState internal functions and several loops to get it to run, some just about five and no loops.
Simplest:
#SingleInstance Force
SetCapsLockState, Off
~CapsLock::
If (Tog:=!Tog)
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
else
SplashTextOff
return
How does: If (Tog:=!Tog) get this code running so easily? Tog is just a variable not initiated, and each time the CapsLock is pressed it is continuously changing its value from 1 to 0
It seems to be acting as a Flag in the code? what am I missing in this line:
If (Tog:=!Tog)
What makes it evaluate different each time?
This is one below is another approach with A = 0 working as a switch, I made this one and it doesn't quite get as simple as I'd like it to be but it does the job.
Longer code:
#SingleInstance Force
SetCapsLockState, Off
~CapsLock::
If (A = 0)
{
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
A=1
}else
{
SplashTextOff
A=0
}
return
Longest code:
This last one gets the same result but checks the actual physical state of the key It wouldn't rely on SetCapsLockState, Off at the top of the script to make sure a switch will do the rest of the work in just one line as the simpler one.
#SingleInstance Force
#Persistent
SetTimer, StateCapsLockON_Timer, 100
Return
~CapsLock::
StateCapsLockON_Timer
If GetKeyState("CapsLock", "T")
{
SetTimer, StateCapsLockOFF_Timer, 100
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
SetTimer, StateCapsLockON_Timer, Off
}
Return
StateCapsLockOFF_Timer:
If !GetKeyState("CapsLock", "T")
{
SetTimer, StateCapsLockOFF_Timer, Off
SplashTextOff
SetTimer, StateCapsLockON_Timer, On
}
Return
Any good ideas about the way If (Tog:=!Tog) works in the simplest of these three examples?
I got this now, check logical-not on this link:
https://lexikos.github.io/v2/docs/Variables.htm
If the operand (In this case Tog) is blank or 0, the result of applying logical-not (or !Tog) is 1, which means "true". Otherwise, the result is 0 (false)
if (Tog = 0)
Tog = 1
would bring the same result as:
If Tog:=!Tog
Because an operation was taking place before the If even checked the changed value, if wasn't just comparing data, the operation was happening before the if since the values inside the parenthesis were not just being read but were also being changed and the variable being reassigned.
(expression) Any sub-expression enclosed in parentheses. For example, (3 + 2) * 2 forces 3 + 2 to be evaluated first.
The key difference is the usage of the assignment operator := as opposed to the comparing operator =. Since, as you've seen, you can evaluate expressions in an if-statement, you can actually include both operators in the same if-statement. Here's an example:
f1::
If (( test := 3+2 ) = 5 )
MsgBox
Return
Here "test" is first being assigned the sum of 3+2, then compared to 5. So, the key is that if-statements allow assignments to take place and that assignments take place first, that is, before anything is compared and evaluated to be true or false.
If there is no comparing operator (= , <, >, <=, >=), as is the case in your toggle, it just evaluates whether the variable itself is true or false. If the variable is blank, 0, or false, it evaluates to false; everything else is true, even the string "false".
Now for the fun bit. We can actually reduce your code to one line if we use Progress with the "zh0" option.
~CapsLock::Progress , % ( Tog := !Tog ) ? "zh0 w350 h35" : "Off" ,, [CapsLock] Activated. , Wanted !
Unfortunately, this isn't possible with SplashText since these are actually two separate commands. But the upside is that Progress actually has a lot more options available, so you can change the font size and color, etc.
It seems Smalltalk implementations misses an algorithm which return all the indices of a substring in a String. The most similar ones returns only one index of an element, for example : firstIndexesOf:in: , findSubstring:, findAnySubstring: variants.
There are implementations in Ruby but the first one relies on a Ruby hack, the second one does not work ignoring overlapping Strings and the last one uses an Enumerator class which I don't know how to translate to Smalltalk. I wonder if this Python implementation is the best path to start since considers both cases, overlapping or not and does not uses regular expressions.
My goal is to find a package or method which provides the following behavior:
'ABDCDEFBDAC' indicesOf: 'BD'. "#(2 8)"
When overlapping is considered:
'nnnn' indicesOf: 'nn' overlapping: true. "#(0 2)"
When overlapping is not considered:
'nnnn' indicesOf 'nn' overlapping: false. "#(0 1 2)"
In Pharo, when a text is selected in a Playground, a scanner detects the substring and highlights matches. However I couldn't find a String implementation of this.
My best effort so far results in this implementation in String (Pharo 6):
indicesOfSubstring: subString
| indices i |
indices := OrderedCollection new: self size.
i := 0.
[ (i := self findString: subString startingAt: i + 1) > 0 ] whileTrue: [
indices addLast: i ].
^ indices
Let me firstly clarify that Smalltalk collections are 1-based, not 0-based. Therefore your examples should read
'nnnn' indexesOf: 'nn' overlapping: false. "#(1 3)"
'nnnn' indexesOf: 'nn' overlapping: true. "#(1 2 3)"
Note that I've also taken notice of #lurker's observation (and have tweaked the selector too).
Now, starting from your code I would change it as follows:
indexesOfSubstring: subString overlapping: aBoolean
| n indexes i |
n := subString size.
indexes := OrderedCollection new. "removed the size"
i := 1. "1-based"
[
i := self findString: subString startingAt: i. "split condition"
i > 0]
whileTrue: [
indexes add: i. "add: = addLast:"
i := aBoolean ifTrue: [i + 1] ifFalse: [i + n]]. "new!"
^indexes
Make sure you write some few unit tests (and don't forget to exercise the border cases!)
Edited
It would also be nice if you would tell us what you need to achieve in the "greater picture". Sometimes Smalltalk offers different approaches.
Leandro beat me to the the code (and his code is more efficient), but I have already written it so I'll share it too. Heed his advice on Smalltalk being 1-based => rewritten example.
I have used Smalltalk/X and Pharo 6.1 for the example.
The code would be:
indexesOfSubstring: substringToFind overlapping: aBoolean
| substringPositions aPosition currentPosition |
substringPositions := OrderedSet new. "with overlap on you could get multiple same
positions in the result when there is more to find in the source string"
substringToFindSize := substringToFind size. "speed up for large strings"
aPosition := 1.
[ self size > aPosition ] whileTrue: [
currentPosition := self findString: substringToFind startingAt: aPosition.
(currentPosition = 0) ifTrue: [ aPosition := self size + 1 ] "ends the loop substringToFind is not found"
ifFalse: [
substringPositions add: currentPosition.
aBoolean ifTrue: [ aPosition := aPosition + 1 ] "overlapping is on"
ifFalse: [ aPosition := currentPosition + substringToFindSize ] "overlapping is off"
]
].
^ substringPositions
I have fixed some issues that occured to me. Don't forget to test it as much as you can!
In perl there are hashes, key-value pairs. Does Isabelle/HOL have a builtin such function with the corresponding theorems?
Typically in Isabelle/HOL, you would just use a function of type 'key ⇒ 'value. For instance:
definition "num_animals
≡ (λ_. 0)(''dog'' := 3, ''cat'' := 42, ''mouse'' := 12)"
lemma "num_animals ''dog'' = 3"
by (simp add: num_animals_def)
Here, (λ_. 0) is a function that returns 0 for all input values, while the syntax (''dog'' := 3) modifies the existing function so that the input dog returns 3.
If you want to be able to determine if a function does not contain a particular key, you can use Isabelle/HOL's option type:
definition "num_animals
≡ (λ_. None)(''dog'' := Some 3, ''cat'' := Some 42, ''mouse'' := Some 12)"
lemma "num_animals ''elephant'' = None"
by (simp add: num_animals_def)
There are numerous differences between this and a hash-table. For example, Isabelle will have to perform at least O(n) steps to look up a value in the function in this format. Also, no hashing is going on: key values are stored and compared explicitly. Usually, though, because you are reasoning about these things, and not typically trying to execute these things, this is not a problem.
If you are dealing with larger proof terms, you may need to look into other representations of functions, such as Binary Search Trees in the AFP, though these will be harder to work with.
For some reason, the Maple code
testproc := proc()
LOCAL abc;
abc[1] := 123;
print(eval(parse(cat("abc[", 1, "]"))))
end proc
testproc();
produces
abc_1
whereas (same, but with abc now a GLOBAL variable)
testproc := proc()
GLOBAL abc;
abc[1] := 123;
print(eval(parse(cat("abc[", 1, "]"))))
end proc
produces (what I want)
123
What do I need to do so that I can evaluate a concatenated string involving a local variable? Many thanks for any help! :)
When you use parse, it operates as if the text was in its own file or entered at the top level. It doesn't have the context of lexically scoped variables.
You could do something like
eval(parse(cat("abc[",1,"]")),convert('abc',`global`)='abc');
If you want to handle multiple locals, use a set for the second argument to eval.
I assume you have some reason for going through the string form. For straight object manipulation, it isn't usually a good idea.
I recently had the necessity of rewriting a javascript function in javascript, dynamically. The ease with which I did it, and how fun it was, astounded me.
Over here I've got some HTML:
<div id="excelExport1234"
onclick="if(somestuff) location.href='http://server/excelExport.aspx?id=56789&something=else'; else alert('not important');"
>Click here to export to excel</div>
And I couldn't change the outputted HTML, but I needed to add an extra parameter to that link. I started thinking about it, and realized I could just do this:
excelExport = $('excelExport1234');
if (needParam)
eval('excelExport.onclick = ' + excelExport.onclick.toString().replace("excelReport.aspx?id", "excelReport.aspx?extraParam=true&id") + ';');
else
eval('excelExport.onclick = ' + excelExport.onclick.toString().replace("extraParam=true&", "") + ';');
And it worked like a champ! excelExport.onclick returns a function object which I convert to a string, and do some string manip on. Since it's now in the form of "function() { ... }", I just go back and assign it to the onclick event of the dom object. It's a little ugly having to use eval, but AFAIK there isn't a javascript function constructor that can take a string of code and turn it into an object nicely.
Anyway, my point isn't that I'm super clever (I'm not), my point is that this is cool. And I know javascript isn't the only language that can do this. I've heard that lisp has had macros for years for this exact purpose. Except to really grok macros you need to really grok lisp, and I don't grok it, I just 'kind of get it'.
So my question is: In what other languages can you (easily) dynamically rewrite functions, and can you show me a simple example? I want to see where else you can do this, and how it's done!
(also, I have no idea what to tag this as, so I took random guesses)
LISP is the ultimate language at this. LISP functions are actual LISP lists, meaning you can manipulate LISP source code as if it were any other data structure.
Here's a very trivial example of how it works:
(define hi
(lambda () (display "Hello World\n")))
;; Displays Hello World
(hi)
(set! hi
(lambda () (display "Hola World\n")))
;; Displays Hola World
(hi)
This, however, is possible in any language where functions are first-class objects. One of the most interesting showcases of the power of this syntax for LISP is in its macro system. I really don't feel I could do the topic justice, so read these links if you're interested:
http://en.wikipedia.org/wiki/Macro_(computer_science)#Lisp_macros
http://cl-cookbook.sourceforge.net/macros.html
I guess it depends on what exactly you define as "easily dynamic rewriting". For example in .Net you have the Func type and lambdas which allows you to define functions as variables or as temporary anonymous functions eg.
int[] numbers = {1, 2, 3, 4, 5};
Func<int[], int> somefunc;
if (someCondition)
{
somefunc = (is => is.Sum());
} else {
somefunc = (is => is.Count());
}
Console.WriteLine(somefunc(numbers).ToString());
The above is a very contrived example of either counting the items in an array of integers or summing then using dynamically created functions subject to some arbitrary condition.
Note - Please don't point out that these things can be easily accomplished without lambdas (which they obviously can) I was simply trying to write a very simple example to demonstrate the concept in C#
Self-modifying code is also called degenerate code. This is generally considered a bad thing, and it used to be a goal of high-level languages to prevent it from being written easily.
This is from the wikipedia entry:
Self-modifying code is seen by some as a bad practice which makes code harder to read and maintain. There are however ways in which self modification is nevertheless deemed acceptable, such as when sub routine pointers are dynamically altered - even though the effect is almost identical to direct modification.
I think that it is the case in most of dynamic languages. Here is an example in Python
def f(x):
print x
def new_function(x): print "hello", x
f("world")
f = new_function
f("world")
The output is
world
hello world
I think that such technique should be used carefully
Scheme allows you to do that.
(define (salute-english name) (display "Hello ") (display name))
(define (salute-french nom) (display "Salut ") (display nom))
Now you redefine a fonction by assigning the salute variable to the right function, either salute-english or salute-french, like this:
(define salute salute-english)
(define (redefined-the-salute-function language)
(if (eq? language 'french)
(set! salute salute-french)
(set! salute salute-english)))
More generaly functional programming language allows you to do that or as functions are first class value. Functions can be manipulated, passed around, sometimes assigned to variables and so on. The list then include: Lisp, Scheme, Dylan, OCaml and SML. Some languages having first class functions includes Python, Ruby, Smalltalk and i think Perl.
Note that when you have an interactive language where you can interactively type your program, the redefinition of functions/methods must be possible: the REPL has to be able to do that, just in case you happen to retype the definition of an already defined functions.
I used to do this all the time in TCL, it was a breeze and worked wonderfully. I could investigate somethings interface over the network and then create a custom-made interface on the fly to access and control things. For example, you could make a custom SNMP interface from a generic SNMP library.
I haven't used it, but C# has some built-in support for generating it's own byte-code, which is fairly impressive.
I've done this sort of thing in C as well, but there it is non-portable and almost never worth the hassle. It is a technique used sometimes for "self-optimizing" code to generate the appropriate C function to optimally process a given data set.
You could do it in C++, but it wouldn't be easy, safe, or recommended.
Generate the text of the source code
invoke the compiler (fork & exec) to build a dynamic library. In gcc, you can pass the source code you want to compile on standard input, it doesn't have to be in a file.
Load the library (LoadLibrary() on windows, dlopen() on linux)
get a function pointer to whatever function you want (GetProcAddress() on windows, dlsym() on linux)
If you want to replace an existing function, if it's a virtual function you could modify the v-table to point to the new function (that part especially is a horrible idea fraught with peril). The location of the v-table or the format of it isn't part of the C++ standard, but all the toolchains I've used have been consistent within themselves, so once you figure out how they do it, it probably won't break.
Easy enough in Perl.
*some_func = sub($) {
my $arg = shift;
print $arg, "\n";
};
some_func('foo');
Re Sam Saffron's request:
*hello_world = sub() {
print "oops";
};
hello_world();
*hello_world = sub() {
print "hello world";
};
hello_world();
In PLSQL:
create or replace procedure test
as
begin
execute immediate '
create or replace procedure test2
as
begin
null;
end;
';
end;
/
Here's something else in Python (in addition to luc's answer), which I am not recommending, but just to show it - there is exec, which can execute a string which you could build to be whatever code...
I/O shown here is from a Python 2.5.2 interpreter session. Just some simple examples of constructing strings to execute from substrings (>>> is the interpreter prompt)...
>>> def_string = 'def my_func'
>>> param_string_1 = '():'
>>> param_string_2 = '(x):'
>>> do_string_1 = ' print "Do whatever."'
>>> do_string_2 = ' print "Do something with", x'
>>> do_string_3 = ' print "Do whatever else."'
>>> do_string_4 = ' print "Do something else with", x'
>>> def_1 = '\n'.join([def_string+param_string_1, do_string_1, do_string_3])
>>> print def_1
def my_func():
print "Do whatever."
print "Do whatever else."
>>> exec def_1
>>> my_func()
Do whatever.
Do whatever else.
>>> def_2 = '\n'.join([def_string+param_string_2, do_string_2, do_string_4])
>>> print def_2
def my_func(x):
print "Do something with", x
print "Do something else with", x
>>> exec def_2
>>> my_func('Tom Ritter')
Do something with Tom Ritter
Do something else with Tom Ritter
>>>
Trivial in Ruby:
def hello_world; puts "oops"; end
hello_world
# oops
def hello_world; puts "hello world"; end
hello_world
# hello world
Of course that example is boring:
require "benchmark"
# why oh _why
class Object
def metaclass; class << self; self; end; end
def meta_eval &blk; metaclass.instance_eval &blk; end
end
class Turtle
end
def make_it_move(klass)
klass.send(:define_method, :move) { |distance|
puts "moving #{distance} meters"
sleep(0.1 * distance)
}
end
make_it_move(Turtle)
turtle = Turtle.new
turtle.move(1)
# moving 1 meters
def profile(instance, method)
instance.meta_eval do
m = instance_method(method)
define_method method do |*a|
puts "Benchmarking #{instance.class} #{method}"
puts Benchmark.measure {
m.bind(instance).call(*a)
}
end
end
end
profile(turtle, :move)
turtle.move(10)
# Benchmarking Turtle move
# moving 10 meters
# 0.000000 0.000000 0.000000 ( 1.000994)
Turtle.new.move(3)
# moving 3 meters
The code above:
Defines a blank class
Adds a method to it
Grabs an instance
Intercepts that method on that instance only
Changing what a function does is supported in a lot of languages, and it's not as complicated as you might think. In functional languages, functions are values, and function names are symbols that are bound to them like any variable. If the language allows you to reassign the symbol to a different function, this is trivial.
I think the more interesting features are the ability to get the source code for a function (toString above) and to create a new function from a string (eval in this case).