Typed list comprehensions in Boo? - boo

I can't seem to grok the correct way to get a properly typed list comprehension in boo. Since the compiler works by inference I'd expect that in this example:
fred as (int)
fred = (1,2,3) # fred is an array of ints
barney = [i for i in fred]
the barney would be a list[of int], since the comprehension is running off of a typed array. However the actual value of barney is just an untyped boo.lang.list: it happens to contain only int's but it won't complain, for example, if I try:
barney.Add("A")
which I would expect to fail but which actually succeeds.
Is there a way to use the comprehension syntax to generate a typed list?

Rodrigo, the creator of boo, provided the answer
fred = (1,2,3) # fred is an array of ints
barney = List[of int](i for i in fred)
The parenthesized expression generates the arguments for the creation of the typed list.

Related

For loops LUA Different Types

I wanted to learn more about for loops, as far as I know there are different types?
For instance,
for i = 1, 5 do
print("hello")
end
^ I know about this one, it's going to print hello 5 times, but there are others like the one below which I do not understand, specifically the index bit (does that mean it is number 1?) and what is the ipairs for
for index, 5 in ipairs(x) do
print("hello")
end
If there are any other types please let me know, I want to learn all of them and if you can provide any further reading I'd be more than greatful to check them out
As you can read in the Lua reference manual
3.3.5 For Statement
The for statement has two forms: one numerical and one generic.
The numerical for loop repeats a block of code while a control
variable runs through an arithmetic progression. It has the following
syntax:
stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
Example:
for i = 1, 3 do
print(i)
end
Will output
1
2
3
You seem familiar with that one. Read the reference manual section for more details.
The generic for statement works over functions, called iterators. On
each iteration, the iterator function is called to produce a new
value, stopping when this new value is nil. The generic for loop has
the following syntax:
stat ::= for namelist in explist do block end namelist ::= Name {‘,’
Name}
Example:
local myTable = {"a", "b", "c"}
for i, v in ipairs(myTable) do
print(i, v)
end
Will ouput
1 a
2 b
3 c
ipairs is one of those iterator functions mentioned:
Returns three values (an iterator function, the table t, and 0) so
that the construction
for i,v in ipairs(t) do body end will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to the first nil value.
Read more about ipairs and pairs here:
https://www.lua.org/manual/5.3/manual.html#pdf-pairs
https://www.lua.org/manual/5.3/manual.html#pdf-ipairs
Of course you can implement your own iterator functions!
Make sure you also read:
Programming in Lua: 7 Iterators and the Generic for
Yes, It will print hello 5 times
According to this answer on Difference between pairs, ipairs, and next?
ipairs does the exact same thing as pairs, but with a slight twist to it.
ipairs runs through the table, until it finds a nil value, or a value that is non-existent, if that makes sense. So, if you ran the script I showed you for pairs, but just replaced pairs with ipairs, it would do the exact same thing

Filter an collection of tuples

I'm playing with iterables and comprehension in Julia and tried to code simple problem: find all pairs of numbers less then 10 whose product is less then 10. This was my first try:
solution = filter((a,b)->a*b<10, product(1:10, 1:10))
collect(solution)
but I got error "wrong number of arguments". This is kind of expected because anonymous function inside filter expects two arguments but it gets one tuple.
I know I can do
solution = filter(p->p[1]*p[2]<10, product(1:10, 1:10))
but it doesn't look nice as the one above. Is there a way I can tell that (a,b) is argument of type tuple and use something similar to syntax in first example?
I don't think there's a way to do exactly as you'd like, but here are some alternatives you could consider for the anonymous function:
x->let (a,b)=x; a*b<10 end
x->((a,b)=x; a*b<10)
These can of course be made into macros if you like:
macro tup(ex)
#assert ex.head == :(->)
#assert ex.args[1].head == :tuple
arg = gensym()
quote
$arg -> ( $(ex.args[1]) = $arg; $(ex.args[2]) )
end
end
Then #tup (a, b) -> a * b < 10 will do as you like.
Metaprogramming in Julia is pretty useful and common for situations where you are doing something over and over and would like specialized syntax for it. But I would avoid this kind of metaprogramming if this were a one-off thing, because adding new syntax means learning new syntax and makes code harder to read.

Understanding hashes

An exercise says:
Create three hashes called person1, person2, and person3, with first
and last names under the keys :first and :last. Then create a params
hash so that params[:father] is person1, params[:mother] is person2,
and params[:child] is person3. Verify that, for example,
params[:father][:first] has the right value.
I did
person1 = {first: "Thom", last: "Bekker"}
person2 = {first: "Kathy", last: "Bekker"}
person2 = {first: "Anessa", last: "Bekker"}
then the params hash in Rails
params = {}
params[:father] = person1
params[:mother] = person2
params[:child] = person3
Now I can ask for father, mother or child's first or last name like so
params[:father][:first] gives me "Thom".
What makes params[:father][:first][:last] return an error? Is there a way to make that return "Thom Bekker"?
I have no way to check if the way I came up with is correct, is there a better way to do the exercise?
Is there a reason why symbol: is better than symbol =>?
Your Return Value is a Single Hash Object
You're misunderstanding the type of object you're getting back. params[:father] returns a single Hash object, not an Array or an Array of hashes. For example:
params[:father]
#=> {:first=>"Thom", :last=>"Bekker"}
params[:father].class
#=> Hash
So, you can't access the missing third element (e.g. :last) because there's no such element within the value of params[:father][:first].
Instead, you could deconstruct the Hash:
first, last = params[:father].values
#=> ["Thom", "Bekker"]
or do something more esoteric like:
p params[:father].values.join " "
#=> "Thom Bekker"
The point is that you have to access the values of the Hash, or convert it to an Array first, rather than treating it directly like an Array and trying to index into multiple values at once.
In Ruby, using square brackets on the Hash or other classes is actually using a method available for an object of that class (this one). When you call these methods in your example, each of these methods will be called and will return its result before the next method is called. So, as you've defined it:
Calling [:father] on params returns the hash represented by person1
[:first] is then called on {first: "Thom", last: "Bekker"}, returning the corresponding value in the hash, "Thom"
[:last] is called on "Thom", which results in an error. Calling square brackets on a string with an integer between them can access the character in a string at that index (person1[:first][0] returns "T"), but "Thom" doesn't have a way of handling the :last symbol inside the square brackets.
There are a number of ways you could get the names printed as you wanted, one of the simplest being combining the string values in person1:
params[:father][:first] + " " + params[:father][:last]
returns "Thom Bekker"
So here's my question, what exactly makes params[:father][:first][:last] return an error? Is there a way to make that return "Thom Bekker"?
Both of these would work
params[:father][:first] + params[:father][:last]
params[:father].values.join(' ')
But maybe it would be better to think about them like the nested structures that they are:
father = params[:father]
name = father[:first] + father[:last]
puts name
To answer your last question, pretend that there's no difference between a hashrocket => and symbol:. This is one where you don't need to care for a long time. Maybe around year 2 start asking this again, but for learning treat them as if they were equivalent.
(Full disclosure, there are differences, but this is a holy war that you really don't want to see played out)

matching array items in rails

I have two arrays and I want to see the total number of matches, between the arrays individual items that their are.
For example arrays with:
1 -- House, Dog, Cat, Car
2 -- Cat, Book, Box, Car
Would return 2.
Any ideas? Thanks!
EDIT/
Basically I have two forms (for two different types of users) that uses nested attributes to store the number of skills they have. I can print out the skills via
current_user.skills.each do |skill| skill.name
other_user.skills.each do |skill| skill.name
When I print out the array, I get: #<Skill:0x1037e4948>#<Skill:0x1037e2800>#<Skill:0x1037e21e8>#<Skill:0x1037e1090>#<Skill:0x1037e0848>
So, yes, I want to compare the two users skills and return the number that match. Thanks for your help.
This works:
a = %w{house dog cat car}
b = %w{cat book box car}
(a & b).size
Documentation: http://www.ruby-doc.org/core/classes/Array.html#M000274
To convert classes to an array using the name, try something like:
class X
def name
"name"
end
end
a = [X.new]
b = [X.new]
(a.map{|x| x.name} & b.map{|x| x.name}).size
In your example, a is current_user.skills and b is other_users.skills. x is simply a reference to the current index of the array as the map action loops through the array. The action is documented in the link I provided.

Evaluation in Scheme

ok, i have this problem here. i was asked to write a function in Scheme, that takes an "environment", and an expression and it returns the value of this expression, for the variable bindings found in the enviroment.
and a definition of a boolean expression is this according to the question below.
edit sorry my question is what does it mean by "it takes an environment" as an argument and what exactly does the function need to do?
evaluate for example "T OR F" and return "F" ???
"<expr> ::= <boolean>
|<variable>
|(not <expr>)
|(or <expr> <expr>)
|(and <expr> <expr>"
An environment is basically a dictionary of variable names to values. So given the environment
var1 = #t
var2 = #f
var3 = #t
and an expression
(or var2 (and T (or var1 var3)))
You would need to substitute the given values of var1, var2, and var3 into the expression, and then evaluate the expression.
Your function will probably be given the environment as some sort of Lisp structure, probably an alist, as one of its parameters.
From what I can determine you have been asked to implement eval.
So you should for starters have:
(define (eval expr env)
... )
where expr can be any of the forms you mention and env would keep the symbols defined (possibly a association list).
The first 2 cases are relatively trivial, the 3rd one, application of the not procedure should also be easy, given not will be in the environment (eg (list (cons 'not not))).
But the harder part lies in the last 2. Both of those are macros, and will require some expansion. The standard definitions/expansions of those should have been given to you. Once expanded, you can simply call eval recursively to evaluate the expanded expression.
Good luck :)
Edit:
Both and and or expands to if, so you will need to implement that too.
By "environment" they probably mean the equivalent of "scope" in other languages. Consider the following C fragment:
if (7 < 100)
{
int j = 2;
if (j < 4)
{
int k = 7, j = 14;
printf("k = %d, j = %d\n", k, j);
}
}
Note that in the outer scope (marked out by the outer set of braces) the only variable is j. In the inner scope there is a new j and a k. So there are three variables here, the outer j, and the inner j and k.
One way of implementing this is to define a scope to be a list of "environments". As you enter a new block, you put another "environment" in your list. When looking up variables by name, you look first in the most recently added "environment". If it isn't found there, you move along the list of environments to the next and look there, and so on.
An "environment" itself is often just a list of pairs, matching up names of variables with values. So it sounds like you are being asked to pass such a list to your function, each pair giving the symbol for a boolean variable and its value. Based on which variables are currently "in scope", you fetch their values out of the environment and use them in the expressions you are evaluating (according to that expression grammar you've been given).
In your case, it sounds like you aren't being asked to worry about which enviroments are in scope. You just have one environment, i.e. one list of pairs.
Sounds like a fair bit of work, good luck!
One reference that might help is:
http://michaux.ca/articles/scheme-from-scratch-bootstrap-v0_9-environments

Resources