Why is this J function not running? - functional-programming

I am attempting to learn J and the book I am using says this is the proper way to define a monadic function
function =: 3:0
function statements
so I followed this format and wrote the folding code. Can you tell me why this is throwing a syntax error when I try to call it with input but if I just call p it returns 3
h=:>:#i.#<.#-: :[: NB. gets all integers less than half of the input :[: forces error if used dyadicly
d=:(0&=|)~ h :[: NB. gets list where if one is set that index from h was a factor of the input y :[: forces error if used dyadicly
p=: 3:0 NB. tells us p is a monadic function
t =: d y
a =: i. 1
while. 1<#t
if. t~:0
a =: a, #t
end.
t=: _1 }. t NB. found first mistake wrong bracket but fixing that doesn't fix it
end.
a*1
)
NB. p gets a list of all integers that are factors of y
p 4
| syntax error
| p 4
p
3
NB. h and d run fine
h 4
1 2
h 7
1 2 3
d 7
1 0 0
d 4
1 1

Firstly, 3:0 parses like (3:) (0), i.e. the monad "3:" applied to the noun "0". That's not what you want; for definitions, you want to use the dyad ":", so you need to separate it from the 3 with a space.
Secondly, you should use =. instead of =: inside the definition, as t and a are local variables.
Several parts can be simplified:
d =: 0 = h | [ NB. does h y divide y
p =: d # h NB. select d y from h y
Same functionality as before, but clearer and faster.

I figured it out sort of I get a stack error instead of a syntax error with monad define instead of using 3:0. I still have to work out a few kinks but I'm making progress.
h =:>:#i.#<.#-:
d =:(0&=#|)~ h
p =: monad define
t =: d y
a =: i.0
while. 1<#t do.
if. {:t~:0 do.
a=:a, #t
end.
t=: _1 }. t
end.
a
)
my latest attempt is a good deal close getting a value error now. Still not sure why its failing but I'll get it soon. I figured it out I was forgetting the required do. after the conditionals adding them fixes everything.

Related

Non-total functions are treated as constants at the type level?

In Type-Driven Development with Idris, ch 6, he says
Type-level functions exist at compile time only ...
Only functions that are total will be evaluated at the type level. A function that isn't total may not terminate, or may not cover all possible inputs. Therefore, to ensure that type-checking itself terminates, functions that are not total are treated as constants at the type level, and don't evaluate further.
I'm having difficulty understanding what the second bullet point means.
How could the type checker claim the code type checks if there's a function that isn't total in its signature? Wouldn't there by definition be some inputs for which the type isn't defined?
When he says constant, does he mean in the same sense as in the docs, like
one: Nat
one = 1
is a constant? If so, how could that enable the type checker to complete its job?
If a type-level function exists at compile time only, does it ever get evaluated if it's not total? If not, what purpose does it serve?
Partial type-level functions are treated as constants in the Skolem sense: invocations of a partial function f remain f with no further meaning.
Let's see an example. Here f is a partial predecessor function:
f : Nat -> Nat
f (S x) = x
If we then try to use it in a type, it will not reduce, even though f 3 would reduce to 2:
bad : f 3 = 2
bad = Refl
When checking right hand side of bad with expected type
f 3 = 2
Type mismatch between
2 = 2 (Type of Refl)
and
f 3 = 2 (Expected type)
So f is an atomic constant here, standing only for itself. Of course, because it does stand for itself, the following still typechecks:
good : f 3 = f 3
good = Refl

Julia #evalpoly macro with varargs

I'm trying to grok using Julia's #evalpoly macro. It works when I supply the coefficients manually, but I've been unable to puzzle out how to provide these via an array
julia> VERSION
v"0.3.5"
julia> #evalpoly 0.5 1 2 3 4
3.25
julia> c = [1, 2, 3, 4]
4-element Array{Int64,1}:
1
2
3
4
julia> #evalpoly 0.5 c
ERROR: BoundsError()
julia> #evalpoly 0.5 c...
ERROR: BoundsError()
julia> #evalpoly(0.5, c...)
ERROR: BoundsError()
Can someone point me in the right direction on this?
Added after seeing the great answers to this question
There is one subtlety to that I hadn't seen until I played with some of these answers. The z argument to #evalpoly can be a variable, but the coefficients are expected to be literals
julia> z = 0.5
0.5
julia> #evalpoly z 1 2 3 4
3.25
julia> #evalpoly z c[1] c[2] c[3] c[4]
ERROR: c not defined
Looking at the output of the expansion of this last command, one can see that it is indeed the case that z is assigned to a variable in the expansion but that the coefficients are inserted literally into the code.
julia> macroexpand(:#evalpoly z c[1] c[2] c[3] c[4])
:(if Base.Math.isa(z,Base.Math.Complex)
#291#t = z
#292#x = Base.Math.real(#291#t)
#293#y = Base.Math.imag(#291#t)
#294#r = Base.Math.+(#292#x,#292#x)
#295#s = Base.Math.+(Base.Math.*(#292#x,#292#x),Base.Math.*(#293#y,#293#y))
#296#a2 = c[4]
#297#a1 = Base.Math.+(c[3],Base.Math.*(#294#r,#296#a2))
#298#a0 = Base.Math.+(Base.Math.-(c[2],Base.Math.*(#295#s,#296#a2)),Base.Math.*(#294#r,#297#a1))
Base.Math.+(Base.Math.*(#298#a0,#291#t),Base.Math.-(c[1],Base.Math.*(#295#s,#297#a1)))
else
#299#t = z
Base.Math.+(Base.Math.c[1],Base.Math.*(#299#t,Base.Math.+(Base.Math.c[2],Base.Math.*(#299#t,Base.Math.+(Base.Math.c[3],Base.Math.*(#299#t,Base.Math.c[4]))))))
end)
I don't believe what you are trying to do is possible, because #evalpoly is a macro - that means it generates code at compile-time. What it is generating is a very efficient implementation of Horner's method (in the real number case), but to do so it needs to know the degree of the polynomial. The length of c isn't known at compile time, so it doesn't (and cannot) work, whereas when you provide the coefficients directly it has everything it needs.
The error message isn't very good though, so if you can, you could file an issue on the Julia Github page?
UPDATE: In response to the update to the question, yes, the first argument can be a variable. You can think of it like this:
function dostuff()
z = 0.0
# Do some stuff to z
# Time to evaluate a polynomial!
y = #evalpoly z 1 2 3 4
return y
end
is becoming
function dostuff()
z = 0.0
# Do some stuff to z
# Time to evaluate a polynomial!
y = z + 2z^2 + 3z^3 + 4z^4
return y
end
except, not that, because its using Horners rule, but whatever. The problem is, it can't generate that expression at compile time without knowing the number of coefficients. But it doesn't need to know what z is at all.
Macros in Julia are applied to their arguments. To make this work, you need to ensure that c is expanded before #evalpoly is evaluated. This works:
function f()
c=[1,2,3,4]
#eval #evalpoly 0.5 $(c...)
end
Here, #eval evaluates its argument, and expands $(c...). Later, #evalpoly sees five arguments.
As written, this is probably not efficient since #eval is called every time the function f is called. You need to move the call to #eval outside the function definition:
c=[1,2,3,4]
#eval begin
function f()
#evalpoly 0.5 $(c...)
end
end
This calls #eval when f is defined. Obviously, c must be known at this time. Whenever f is actually called, c is not used any more; it is only used while f is being defined.
Erik and Iain have done a great job of explaining why #evalpoly doesn't work and how to coerce it into working. If you just want to evaluate the polynomial, however, the easiest solution is probably just to use Polynomials.jl:
julia> using Polynomials
c = [1,2,3,4]
polyval(Poly(c), 0.5)
3.25

Creating a recursive tacit function in J

I'm a newcomer to J and I've been trying to create a Fibonacci function as an exercise (always the second function I create when learning a language). I just can't figure out what exactly is wrong in my way of doing it. I have tried to define it as tacit, but it gets hung if argument is greater than one.
fib =: [ ` (($: (]-1)) + ($: (]-2))) #. (>&1)
I've also attempted to create it explicitly, and that worked fine.
fib =: 3 : 'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'
I tried to create a tacit out of that by replacing 3 with 13, but it threw an error.
fib =: 13 : 'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'
|spelling error
| if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.
| ^
| fib=: 13 :'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'
So, I'm asking for someone to explain what exactly I am doing wrong here.
Here's an alternative that I think is both clearer and more concise:
fibn =: (-&2 +&$: -&1)^:(1&<) M."0
Compare with a more canonical (pseudocode) definition:
fib(n) = fib(n-1) + fib(n-2) if n > 2 else n
First, instead of using [ ` with #. (>&1), which uses a gerund, it's better to use ^:(1&<). For f(n) if cond(n) else n, using the ^: conjunction is more idiomatic; ^:0 means "do nothing" and ^:1 means "do once," so the intent is clear. #. is better suited to nontrivial behavior.
Second, using the & bond/compose conjunction simplifies the train significantly. Repeated uses of [: and ] are rather confusing and opaque. Refactoring using & puts together related operations: first, split n into two, namely n-2 and n-1, and second, add together the fibn of those two numbers.
And, lastly, "0 for list handling and M. for memoizing. M. is rather important from a performance perspective, as a straightforward implementation of the canonical definition will call fib(2) excessively. You can have your cake (a simple definition) and eat it too (good performance) with the built-in memoization adverb.
Source for this particular definition: f0b on this page.
Okay, I found it. I ran only the recursive block through tacit generator and got this block.
13 : '(f y-1) + (f y-2)'
([: f 1 -~ ]) + [: f 2 -~ ]
Then I inserted that to the original piece, getting this.
fib =: [ ` (([: $: 1 -~ ]) + [: $: 2 -~ ]) #. (>&1)
And that works like a charm. I also inserted " 0 to the end to make it accept lists.

Partial application to precompute intermediary results

For the below quardratic formula, I have multiple a but fixed b and c.
I wish to write a partial application function, which execute efficiently, i.e., my function doesn't recompute fixed values (because of b and c).
Here is my solution
let r b c = let z = b *. b in fun a -> (-.b +. sqrt (z-.4.0*.a*.c))/.(a*.2.0);;
I guess this solution can work, but I am not sure whether it is efficient enough. I just made b^2 to be fixed as I saw other parts are all with a.
Anyone can give me a better solution?
Yeah, that's a correct way to deal with the situation at hand. The alternate form doesn't help much (as long this obtains the accuracy you require). You may want to move the 4*c out as well,
let r b c = let z = b *. b and c4 = 4.0 *. c in
fun a -> (-.b +. sqrt (z-.a*.c4))/.(a*.2.0);;

How would you code a program in Prolog to print numbers from 1 to 10 using recursion?

How would you code a program in Prolog to print numbers from 1 to 10 using recursion?
I've tried the following but it doesn't work, can you tell me why?
print_numbers(10) :- write(10).
print_numbers(X) :- write(X),nl,X is X + 1, print_numbers(X).
Your code is very close to working. The problem is that you cannot reuse X, once it is instantiated, it cannot be changed (see here for more details). Use a new variable, like this:
print_numbers(10) :- write(10), !.
print_numbers(X) :- write(X), nl, Next is X + 1, print_numbers(Next).
Adding the cut (!) to the end will prevent the interpreter from asking if you want to see more results.
?- print_numbers(1).
1
2
3
4
5
6
7
8
9
10
Yes
?-
print_from_1_to_10 :-
print_from_X_to_10(1).
print_from_X_to_10(X) :-
(
X > 10
->
fail
;
writeln(X),
NewX is X + 1,
print_from_X_to_10(NewX)
).
Been a seriously long time since I wrote any prolog but I'd probably do things just a little differently. Something like this, though I can't test it at the momment.
print_increasing_numbers(From, To):- From > To, !, write('ERROR: From > To').
print_increasing_numbers(To, To):- !, write(To).
print_increasing_numbers(From, To):- write(From),
nl,
Next is From + 1,
print_increasing_numbers(Next, To).
A key difference here is the !, or cut operation, which stops backtracking. If you don't include it then you will get a solution with the first clause when X is 10,but if you ask for a second solution it will backtrack and match the second clause as well. That would result in a much larger list of numbers than you want.
Just call defineXandY from terminal
defineXandY :-
print_one_to_ten(1,10).
print_one_to_ten(X,Y) :-
X<Y,
write(X),nl,
NewX is X+1,
print_one_to_ten(NewX,Y).

Resources