How to call a method with arguments in Smalltalk - smalltalk

I am new to the programming language Smalltalk and I can't seem to figure out how to call a method with arguments. I've been playing around with some code and created some methods, like for example (in GNU Smalltalk):
bin: n num: k [
| i |
i := 1.
1 to:k do:[:j|
i := i * 2.
].
^i
]
I would now like to call this function and actually get an answer, like for example: bin: 4 num: 2 (don't know how to do this). How can I do that? Is it even right to write 'bin: n num: k' when creating a method like I have done?
Thanks in advance!

First, you need a receiver object, on which you want to invoke that method. You did not indicate in which class you have created your method, so I will just assume that you called it MyClass.
| myObject |
myObject := MyClass new.
Then you can send that message to (invoke that method on) myObject like this:
myObject bin: 4 num: 2
So you just write the message send (which will invoke the method) after the receiver.

Related

Class method name with ^ doesn't get invoked properly

When I make a class method that starts with a ^, and I try to invoke it, it gives me an error.
class C {
method ^test () {
"Hi"
}
}
dd C.new.test;
Too many positionals passed; expected 1 argument but got 2
in method test at .code.tio line 1
in block <unit> at .code.tio line 1
If I make the same method without a leading ^, it works fine.
class C {
method test () {
"Hi"
}
}
dd C.new.test;
"Hi"
I've seen modules expose classes with methods that do start with a ^, which leads to my question. Why am I getting this error when I define a method name that starts with a ^?
TL;DR The method is getting invoked properly. The ^ in foo.^bar indicates a "metamethod". This is neither an instance method nor a class method. Metamethods are passed both an invocant, as is the case for all methods, and another "original invocant" object as the first argument.
Most users will never need to think about this stuff. But you've asked, so let's dig in...
Metamethods
Quoting the Meta-object protocol (MOP) Raku doc page:
Raku is built on a meta object layer.
This MOP layer defines various built in "metamethods" that you can use.
For example:
say .^attributes given class bar { has Int $!foo }
This displays (Int $!foo). The .^attributes method call is a metamethod. It's called on the (typically invisible) metaobject that determines how a Raku type works behind the scenes. In this case, it returns the attributes (has variables) of a class.
But there can also be user defined metamethods. One way to declare these is in an otherwise ordinary class:
class {
has Int $!foo;
method ^attributes ($arg) { self, $arg }
}
say baz.^attributes
The above baz class includes an ^attributes metamethod declaration that overrides the built in metamethod. Of special note, I've added an argument. ALL metamethods get at least one argument (in addition to a regular invocant).
With this declaration, instead of (Int $!foo) in response to an .^attributes call you instead get the list self, $arg from the .^attributes method in the baz class.
Note how self is neither a baz instance object nor a baz type object -- instead it's Perl6::Metamodel::ClassHOW+{<anon>}.new -- whereas $arg is a baz (type) object.
The rest of this answer explains what's going on in more detail.
A recap of an ordinary method call
First, let's recap a typical method call.
The syntax foo.bar results in a "bar" method (message) being dispatched to foo.
If foo is an instance of a class, "bar" is dispatched to that instance. Such a method call is sometimes referred to as an "instance method".
If foo is a type object corresponding to a class, "bar" is dispatched to that type object. Such a method call is sometimes referred to as a "class method".
In both cases, "bar" is dispatched to foo.
#foo.^bar
The syntax foo.^bar is different.
Read the ^ as pointing up to another object that hovers invisibly above foo, or indeed anything related to the kind of type foo is.
Such objects are HOW objects that determine How Objects Work. These HOW objects typically stay invisible, making things work nicely, with users blissfully unaware of their existence and the work they're doing.1
A method call of the form foo.^bar ordinarily results in Raku dispatching a metamethod call to foo's HOW object.
These metamethods require two invocant-like arguments. There's the HOW object. This is passed as the regular invocant. Then there's the foo object. This is passed as a first ordinary argument to the metamethod.
So that's what ordinarily happens when you call foo.^bar -- a metamethod call is dispatched to foo's HOW object and foo is passed as an ordinary argument storing what could be said to be "the original invocant".
#foo.^bar when there's no built in .^bar metamethod
If you call foo.^bar when there's no such method you'll get an error:
42.^bar
yields:
No such method 'bar' for invocant of type 'Perl6::Metamodel::ClassHOW'
Note how the invocant type is a metamodel class, not 42 or Int.
If a user defined class declares a ^.bar, then Raku calls it, passing the instance/class's HOW object as the invocant and the "original invocant" (foo) as the first ordinary argument:
class foo {
method ^bar ($arg) { self, $arg }
}
say foo.^bar; # (Perl6::Metamodel::ClassHOW+{<anon>}.new (foo))
Footnotes
1 Calling .HOW on an object returns its HOW:
say .HOW given class {} # Perl6::Metamodel::ClassHOW
HOW objects are part of the MOP, a layer deep down inside Raku.
Most devs will never need to explicitly dig down to this level.
If you dig even deeper you're leaving specified Raku. In Rakudo the .HOW of a HOW object is typically an NQP object:
say ((.HOW.new given class {}).HOW).^name; # NQPClassHOW

Smalltalk Pharo - unable to update a class instance variable in a thread

I have a class called ThreadTesting, and within that class I have an instance variable called 'col' (which is an array). My goal is to populate it through a thread, wait for the thread to finish and then output its contents.
ThreadTesting new callThread.
ThreadTesting class:
initialize
super initialize.
semaphore := Semaphore new.
col := Array new: 10.
callThread method:
callThread
self runThread.
semaphore wait.
Transcript show: 'Thread finished';cr.
col do:
[ :each | Transcript show: each ; cr].
runThread method:
runThread
|pr|
pr := [
[ 1 to: 10 do: [ :i |
col at: i put: i
]].
semaphore signal.
] fork.
Output:
It is all set to nil and I don't know why.
Your problem is simply that you're defining a block that will populate your array, but you're not actually doing anything with it, i.e. it never gets called.
I think what you want is to simply remove the extra [ and ] around that block, then it will actually be a piece of code that gets executed. You also don't need to assign your outer block to a temporary variable (and if you do want to keep it, please honour the spirit of Smalltalk and call it process, not pr - AAAAB... abbreviations are almost always bad. Similarly, I'd never call an Array something like col - that's misleading and abbreviated...). So your runThread method should look like this:
runThread
[
1 to: 10 do: [ :eachIndex |
numbers at: eachIndex put: eachIndex
].
semaphore signal
] fork
So you're now declaring a block that populates your array and signals your semaphore, and forking it as a new process, whereas previously you were declaring an outer block that declared an inner block (but never did anything with it, it just sat there) and signalled your semaphore, and then forked it as a new process.

Implementation of new with argument in smalltalk

I basically want to implement new which can accept argument e.x obj := SomeClass new: 'a'. I tried to implement this way
initialize: bdata
data := bdata
But this doesn't work. seems like I am doing some silly mistake because of lack of knowledge. I try to google it but couldn't find any example. Please help.
In Smalltalk, new and new: are not keywords, but regular messages. They are simply implemented by the object's class. To write a method for an objects's class (rather than for an instance), click the "class" button in the system browser. There, you could implement your new: method.
Note, however, that it is usually not a good idea to name your own instance creation method new:. Since this is a regular method, you can name it anything you want. For example, MyClass withBData: foo. Make it a nice descriptive name. It could look like
withBData: bdata
| inst |
inst := self new.
inst bdata: bdata.
^inst
Your code is too short to tell what is wrong. In general you should have an initialize with arg, something like this:
initialize: arg
self initialize.
instVar := arg
Then you can implement new: like this:
new: arg
^ self basicNew
initialize: arg;
yourself
Note that new is implemented as self basicNew initialize, so if you are calling initialize from your custom initialization method, you shouldn't use new in your custom new, use basicNew instead
You can use the basicNew method if you need to use your argument in the initialize method (as Uko mentions in his answer above).
withBData: bdata
^ (self basicNew bdata: bdata) initialize

What's the left-hand side of a method invocation called?

Given the following line
cat.meow(10, x);
"meow" is the "function" or "method" being called
10 is the "first argument"
x is the "second argument"
What is cat called?
I'm dissatisfied with the answer, cat is called "the object". I want to say I've heard it called the "receiver", but I don't remember where I've heard that.
Considering both 10 and x can be objects, calling cat "the object" doesn't help me distinguish this component from the argument components.
This makes it difficult to discuss the various components that makeup a function call.
It is called the “subject” following the subject-verb-object sentence structure that object-oriented programming mimics:
cat.meow(10, x);
|_||___||_____|
| | |
| | +--> object (the arguments list is a tuple object)
| |
| +--> verb (the verb is the method name with the dot)
|
+--> subject (quite self explanatory)
I should clarify that I call it the “subject” because it makes sense to me. However, there's no consensus on this nomenclature. Everyone has their own opinions on what it should be called.
An object is an instance of a specific class. You can use it to say cat is an instance of class [put class name here], just like 10 is an instance of Integer.
Normally we call that object. According to your logic, take it in this way
meow(self,10, x) - This is the actual function where self is an object like 10 and x
Same in this case - cat.meow(10,x)

Is it really all about message passing in smalltalk

I'm new to smalltalk and I'm impressed with the fact that there are only just 6 keywords in the language (self, super, true, false, nil & thisContext), and how pure it is in having almost everything as message passing, eg. looping using whileTrue, if/else using ifTrue, etc ... which are way different from what I'm used to in other languages.
Yet, there are cases where I just cannot make sense of how message passing really fit in, these include:
the assignment operator :=
the cascading operator ;
the period operator .
the way to create a set #( ... )
These aren't message passing, right?
As you've discovered, there's still some actual Smalltalk syntax. Block construction, literal strings/symbols/comments, local variable declaration (|...|), and returning (^) are a few things you didn't mention which are also syntax.
Some extensions (e.g. #(...), which typically creates an Array, not a set) are certainly expressible otherwise, for example #(1 2 3) is equivalent to Array with: 1 with: 2 with: 3; they're just there to make the code easier to read and write.
One thing that might help clarify : self, super, true, false, nil & thisContext are data primitives, rather than keywords.
They are the only 6 data primitives. These 6 are also known as pseudo-variables. Absolutely every other thing is an instance of Class Object or its subclasses.
There are very few pre-defined keywords in Smalltalk. They can be written in a very condensed form.
A famous example is Smalltalk Syntax on a Postcard (link)
exampleWithNumber: x
| y |
true & false not & (nil isNil) ifFalse: [self halt].
y := self size + super size.
#($a #a "a" 1 1.0)
do: [ :each |
Transcript show: (each class name);
show: ' '].
^x < y
Here's the comment for this method - which is larger than the method itself:
"A method that illustrates every part of Smalltalk method syntax
except primitives. It has unary, binary, and keyboard messages,
declares arguments and temporaries, accesses a global variable
(but not an instance variable), uses literals (array, character,
symbol, string, integer, float), uses the pseudo variables
true, false, nil, self, and super, and has sequence, assignment,
return and cascade. It has both zero argument and one argument blocks."