How to type-hint in Hy - type-hinting

Is it possible to type-hint variables and return values of functions in Hy language?
# in python we can do this
def some_func() -> str:
return "Hello World"

Yes... Hy implements PEP 3107 & 526 annotations since at least 8 Oct 2019 (see this pull request: https://github.com/hylang/hy/pull/1810)
There is the #^ form as in the example below (from the documentation: https://docs.hylang.org/en/master/api.html?highlight=annotation##^)
; Annotate the variable x as an int (equivalent to `x: int`).
#^int x
; Can annotate with expressions if needed (equivalent to `y: f(x)`).
#^(f x) y
; Annotations with an assignment: each annotation (int, str) covers the term that
; immediately follows.
; Equivalent to: x: int = 1; y = 2; z: str = 3
(setv #^int x 1 y 2 #^str z 3)
; Annotate a as an int, c as an int, and b as a str.
; Equivalent to: def func(a: int, b: str = None, c: int = 1): ...
(defn func [#^int a #^str [b None] #^int [c 1]] ...)
; Function return annotations come before the function name (if it exists)
(defn #^int add1 [#^int x] (+ x 1))
(fn #^int [#^int y] (+ y 2))
and also the extended form annotate macro. There is also the of macro (detailed here https://hyrule.readthedocs.io/en/master/index.html#hyrule.misc.of):

Related

Is this scala function using right-fold or left-fold?

def calculate(f: Int => Int, sumProd:(Int, Int)=>Int, n: Int, a:Int, b:Int):Int =
if (a>b) n
else sumProd(f(a), calculate(f, sumProd, n, a+1, b))
This scala function can in a chosen number area (a to b) do chosen calculations with them:
example calling:
calculate(x=>2*x, (x,y)=>x+y, 0, 2 , 4)
this calculates: 2*2 + 2*3 + 2*4 = 18
Which folding(right- or left folding) is this function using? And how to see that?
further example callings for the function:
calculate(x=>2+x, (x,y)=>x*y,1, 2 , 4)
calculate(x=>2+x, (a,b)=>a+b,0, 1, 5)
calculate(x=>2*x, (a,b)=>a+b,0, 1, 5)
What you have is equivalent to, in pseudocode,
calculate(f, sumProd, n, a, b)
=
fold-right( sumProd, n, map(f, [a .. b]))
where [a .. b] denotes a list of numbers from a to b, inclusive, increasing by the step of 1. In other words, it is the same as
=
sumProd( f(a),
sumProd( f(a2),
sumProd( f(a3),
...
sumProd( f(b), n) ... )))

Nim operator overloading

Just started programming in the Nim language (which I really like so far). As a learning exercise I am writing a small matrix library. I have a bunch more code, but I'll just show the part that's relevant to this question.
type
Matrix*[T; nrows, ncols: static[int]] = array[0 .. (nrows * ncols - 1), T]
# Get the index in the flattened array corresponding
# to row r and column c in the matrix
proc index(mat: Matrix, r, c: int): int =
result = r * mat.ncols + c
# Return the element at r, c
proc `[]`(mat: Matrix, r, c: int): Matrix.T =
result = mat[mat.index(r, c)]
# Set the element at r, c
proc `[]=`(mat: var Matrix, r, c: int, val: Matrix.T) =
mat[mat.index(r, c)] = val
# Add a value to every element in the matrix
proc `+=`(mat: var Matrix, val: Matrix.T) =
for i in 0 .. mat.high:
mat[i] += val
# Add a value to element at r, c
proc `[]+=`(mat: var Matrix, r, c: int, val: Matrix.T) =
mat[mat.index(r, c)] += val
# A test case
var mat: Matrix[float, 3, 4] # matrix with 3 rows and 4 columns
mat[1, 3] = 7.0
mat += 1.0
# add 8.0 to entry 1, 3 in matrix
`[]+=`(mat, 1, 3, 8.0) # works fine
All this works fine, but I'd like to be able to replace the last line with something like
mat[1, 3] += 4.0
This won't work (wasn't expecting it to either). If I try it, I get
Error: for a 'var' type a variable needs to be passed
How would I create an addition assignment operator that has this behavior? I'm guessing I need something other than a proc to accomplish this.
There are two ways you can do this:
Overload [] for var Matrix and return a var T (This requires the current devel branch of Nim):
proc `[]`(mat: Matrix, r, c: int): Matrix.T =
result = mat[mat.index(r, c)]
proc `[]`(mat: var Matrix, r, c: int): var Matrix.T =
result = mat[mat.index(r, c)]
Make [] a template instead:
template `[]`(mat: Matrix, r, c: int): expr =
mat[mat.index(r, c)]
This causes a problem when mat is not a value, but something more complex:
proc x: Matrix[float, 2, 2] =
echo "x()"
var y = x()[1, 0]
This prints x() twice.

Why is the anonymous function and function in Scala constructed like this?

In SICP 1.3.2, there is this function
(define (f x y)
((lambda (a b)
(+ (* x (square a))
(* y b)
(* a b)))
(+ 1 (* x y))
(- 1 y)))
Now after 30 minutes chasing after errors, I found this page and it provided this function
def f_lambda(x: Int, y: Int) =
(((a: Int, b: Int) => ((x * square(a)) + (y * b) + (a * b)))
(1 + (x * y), 1 - y))
I do not understand why it is surrounded (like a fort) with parentheses.
Edit: Sorry, my real issue is I don't understand why this function is constructed the way it is. In other words, why are all the parentheses needed in the first place. This looks completely "foreign" compared to the Scala code I've seen so far.
First, it is certainly possible to eliminate a few of the pairs of parentheses in the particular example you give above, although in the case of the outermost pair, this does require putting part or all of the last line on the end of the preceding line:
def f_lambda2(x: Int, y: Int) =
((a: Int, b: Int) => (x * square(a) + y * b + a * b))(1 + x * y, 1 - y)
That said, you may - as with any code - choose to put in extra parentheses to clarify things (eg. around multiplications to make precedence clearer).
Second, there are alternate ways to write such a function which can make what is going on clearer for any reader. This does mean less brevity of code, but I think the clarity gained can definitely be worth it:
def f_lambda3(x: Int, y: Int) = {
def inner(a: Int, b: Int) = (x * square(a)) + (y * b) + (a * b)
inner(1 + x * y, 1 - y)
}
Overall, just because the most efficient, compact representation of a coding concept might arguably involve bracket madness (yay, Lisp!), this doesn't mean this has to be carried over to Scala, which has many much more accessible constructs for writing exressive code.
I don't understand either. You can strip a few off:
def f_lambda(x: Int, y: Int) =
((a: Int, b: Int) => (x * square(a)) + (y * b) + (a * b)) (1 + (x * y), 1 - y)
Or if you want to rely on the fact that multiplication takes precedence over addition:
def f_lambda(x: Int, y: Int) =
((a: Int, b: Int) => x * square(a) + y * b + a * b) (1 + x * y, 1 - y)
Personally I think the first is a bit more readable.
Edit:
Breaking this down a bit, this is declaring an anonymous function which takes two Ints as arguments, styled "a" and "b":
(a: Int, b: Int) => x*square(a) + y*b + a*b
Note this is still using x and y (being the arguments to the outer method). It is then applying this inner function using a = 1 + xy and b = 1 - y.
So substituting, I believe you end up with:
x*square(1 + x*y) + y*(1 - y) + (1 + x*y)*(1 -y)
Why not write it this way in the first place (or using an inner function as Shadowland has)? Well, it's a matter of style and context I guess, so I can't really guess the author's initial intention. The point is that Scala is flexible enough to allow lots of different styles by which you can express the same thing.

Cannot understand 'functions as arguments' recursion

I'm taking a functional programming languages course and I'm having difficulty understanding recursion within the context of 'functions as arguments'
fun n_times(f , n , x) =
if n=0
then x
else f (n_times(f , n - 1 , x))
fun double x = x+x;
val x1 = n_times(double , 4 , 7);
the value of x1 = 112
This doubles 'x' 'n' times so 7 doubled 4 times = 112
I can understand simpler recursion patterns such as adding numbers in a list, or 'power of' functions but I fail to understand how this function 'n_times' evaluates by calling itself ? Can provide an explanation of how this function works ?
I've tagged with scala as I'm taking this course to improve my understanding of scala (along with functional programming) and I think this is a common pattern so may be able to provide advice ?
If n is 0, x is returned.
Otherwise, f (n_times(f , n - 1 , x)) is returned.
What does n_times do? It takes the result of calling f with x, n times, or equivalently: calls f with the result of n_times(f, n - 1, x) (calling f n-1 times on x).
Note by calling f i mean for example:
calling f 3 times: f(f(f(x)))
calling f 2 times: f(f(x))
Just expand by hand. I'm going to call n_times nx to save space.
The core operation is
nx(f, n, x) -> f( nx(f, n-1, x))
terminating with
nx(f, 0, x) -> x
So, of course,
nx(f, 1, x) -> f( nx(f, 0, x) ) -> f( x )
nx(f, 2, x) -> f( nx(f, 1, x) ) -> f( f( x ) )
...
nx(f, n, x) -> f( nx(f,n-1,x) ) -> f( f( ... f( x ) ... ) )
Function n_times has a base case when n = 0 and an inductive case otherwise. You recurse on the inductive case until terminating on the base case.
Here is an illustrative trace:
n_times(double, 4, 7)
~> double (n_times(double, 3, 7)) (* n = 4 > 0, inductive case *)
~> double (double (n_times(double, 2, 7))) (* n = 3 > 0, inductive case *)
~> double (double (double (n_times(double, 1, 7)))) (* n = 2 > 0, inductive case *)
~> double (double (double (double (n_times(double, 0, 7))))) (* n = 1 > 0, inductive case *)
~> double (double (double (double 7))) (* n = 0, base case *)
~> double (double (double 14))
~> double (double 28)
~> double 56
~> 112
It is the same recursion thinking what you know already, just mixed with another concept: higher order functions.
n_times gets a function (f) as a parameter, so n_times is a higher order function, which in turn is capable to apply this f function in his body. In effect that is his job, apply f n times to x.
So how you apply f n times to x? Well, if you applied n-1 times
n_times(f , n - 1 , x)
, then you apply once more.
f (n_times(f , n - 1 , x))
You have to stop the recursion, as usual, that is the n=0 case with x.

How to divide a pair of Num values?

Here is a function that takes a pair of Integral
values and divides them:
divide_v1 :: Integral a => (a, a) -> a
divide_v1 (m, n) = (m + n) `div` 2
I invoke the function with a pair of Integral
values and it works as expected:
divide_v1 (1, 3)
Great. That's perfect if my numbers are always Integrals.
Here is a function that takes a pair of Fractional
values and divides them:
divide_v2 :: Fractional a => (a, a) -> a
divide_v2 (m, n) = (m + n) / 2
I invoke the function with a pair of Fractional
values and it works as expected:
divide_v2 (1.0, 3.0)
Great. That's perfect if my numbers are always Fractionals.
I would like a function that works regardless of whether the
numbers are Integrals or Fractionals:
divide_v3 :: Num a => (a, a) -> a
divide_v3 (m, n) = (m + n) ___ 2
What operator do I use for _?
To expand on what AndrewC said, div doesn't have the same properties that / does. For example, in maths, if a divided by b = c, then c times b == a. When working with types like Double and Float, the operations / and * satisfy this property (to the extent that the accuracy of the type allows). But when using div with Ints, the property doesn't hold true. 5 div 3 = 1, but 1*3 /= 5! So if you want to use the same "divide operation" for a variety of numeric types, you need to think about how you want it to behave. Also, you almost certainly wouldn't want to use the same operator /, because that would be misleading.
If you want your "divide operation" to return the same type as its operands, here's one way to accomplish that:
class Divideable a where
mydiv :: a -> a -> a
instance Divideable Int where
mydiv = div
instance Divideable Double where
mydiv = (/)
In GHCi, it looks like this:
λ> 5 `mydiv` 3 :: Int
1
λ> 5 `mydiv` 3 :: Double
1.6666666666666667
λ> 5.0 `mydiv` 3.0 :: Double
1.6666666666666667
On the other hand, if you want to do "true" division, you would need to convert the integral types like this:
class Divideable2 a where
mydiv2 :: a -> a -> Double
instance Divideable2 Int where
mydiv2 a b = fromIntegral a / fromIntegral b
instance Divideable2 Double where
mydiv2 = (/)
In GHCi, this gives:
λ> 5 `mydiv2` 3
1.6666666666666667
λ> 5.0 `mydiv2` 3.0
1.6666666666666667
I think you are looking for Associated Types which allows for implicit type coercion and are explained quite nicely here. Below is an example for the addition of doubles and integers.
class Add a b where
type SumTy a b
add :: a -> b -> SumTy a b
instance Add Integer Double where
type SumTy Integer Double = Double
add x y = fromIntegral x + y
instance Add Double Integer where
type SumTy Double Integer = Double
add x y = x + fromIntegral y
instance (Num a) => Add a a where
type SumTy a a = a
add x y = x + y