'==' type and pattern matching - wait for the other recursive calls and do nothing on a case - syntax

I have two questions concerning OCaml.
Firstly, what does the == means when defining a type.
For example you can see at the end of this page the following code:
type compteur == int;;
Then what is the difference with:
type compteur = int;;
Moreover I have an other question concerning pattern matching.
How to say that you want to return nothing on a case.
For example let's say I have a function f that returns a boolean:
let rec f v = function
| t when t<v -> true
| t when t > v -> f (t-1)
| t when t = v -> (* here a code to say that you do nothing, and wait for the other recursive call *)

type compteur == int is a syntax error. The only valid way to define a type alias is with =, not ==. It's just a typo on the page you linked.
How to say that you want to return nothing on a case.
The only way to return nothing from a function would be to exit the program, raise an exception or loop (or recur) infinitely. Otherwise a function always returns a value.
here a code to say that you do nothing, and wait for the other recursive call
What other recursive call? In the case that t = v only the code for that case will run. There is no other code to wait on.

Related

Argument in fuction call inside function definition is not being replaced in Maxima

The problem
Consider the following script written in Maxima
$ cat main.max
foo(a) ::= block(
if a = 0 then return(0) else return(1)
)$
bar(a) ::= block(
return(foo(a))
)$
foo(0);
bar(0);
Executing this script yields to
$ cat main.max | maxima --very-quiet
0
1
The question
Isn't it supposed that calling foo by itself results the same as if it is called from another function (in this scenario, bar)?
Here there is another example
$ cat main.max
foo(a) ::= block(disp(a))$
bar(a) ::= block(foo(a))$
foo(0)$
bar(0)$
$ cat main.max | maxima --very-quiet
0
a
In other words: Why isn't maxima replacing the argument that is passed to bar in the foo function call which is located within bar?
Additional context
This is the version that I'm currently using
$ maxima --version
Maxima 5.43.2
::= defines a function which quotes (does not evaluate) its arguments, and the return value of the function is evaluated by the caller. Such a function is conventionally called a "macro" for historical reasons.
I think you want an ordinary, argument-evaluating function, which is defined by :=. Try substituting := for ::= in your function definitions -- when I try that, I get 0 for bar(0) as expected.
Macros are useful, but in relatively narrow circumstances. I think ordinary functions are much more common than macros.
As an aside, in the functions which you have shown, block and return are unneeded. My advice is to just leave them out and make the functions more succinct and therefore more clear. E.g.
foo(a) := if a = 0 then 0 else 1;
bar(a) := foo(a);
Finally, note that = is only literal comparison, not equivalence; equivalence is tested with equal. E.g. suppose x is not otherwise defined. Then is(x = 0) yields false, but is(equal(x, 0)) yields the expression equal(x, 0). Depending on what you're doing, one or the other might be appropriate.

It is applied to too many arguments; maybe you forgot a `;'

I am trying to write a code that calculate the size of a list.
Here is what I've done:
let rec l = function
| [] -> 0
| t::q -> 1 + l q
print_int(l ([1;2;3;4]))
The problem is that it's saying me :
It is applied to too many arguments; maybe you forgot a `;'.
When I put the double semicolon ;; at the end of the definition of l it works well, yet I've read that ;; is not useful at all if you are not coding in the REPL, so here I don't see why it's giving me this error.
The following
print_int(l [1;2;3;4])
is a toplevel expression. Such expression needs to be preceded by ;;:
;; print_int(l [1;2;3;4])
Another option is to make this toplevel expression a binding with
let () = print_int(l [1;2;3;4])
When parsing the code the parser advances until it hits l q. At this point there could be more arguments that should get applied to the function l. So the parser keeps going and the next thing it finds is the value print_int. Another argument to l. Which gives you your error.
The parser has no way of knowing that you had finished the code for the function l. In the top level the special token ;; is used to tell the parser that the input is finished and it should evaluate the code now. After that it starts paring the remaining input again.
Now why doesn't compiled code also have the ';;' token?
Simply because its not needed. In compiled code the line print_int(l [1;2;3;4]) is not valid input. That would be a statement you want to execute and functional languages have no such thing. Instead print_int(l [1;2;3;4]) is an expression that returns a value, () in this case, and you have to tell the compiler what to do with that value. A let () = tells the compiler to match it against (). And the let ... also tells the compiler that the previous let rec l ... has finished. So no special ;; token is needed.
Or think of it this way: In the top level there is an implicit let _ = if your input doesn't start with let. That way you can just type in some expression and see what it evaluates to without having to type let _ = every time. The ';;' token still means "evaluate now" though and is still needed.

how to force to start next expression in ocaml

I want to write a function that implements basic usage of grep: matching a pattern in a file. And I want to match_file_pattern to return a list of matched lines. But the code here cannot compile, the error is:
Error: This expression has type string list
but an expression was expected of type unit
And the code is:
let match_file pattern file_name =
let matched_lines = ref [] in
let ic = open_in file_name in
try
while true
do
let line = input_line ic in
if (Str.string_match (Str.regexp pattern) line 0)
then
matched_lines := line::!matched_lines
done;**(*!matched_lines*)**(*I need add this to compile successfully*)
with End_of_file ->
close_in ic;
List.rev !matched_lines;;
I think the error is caused by in ocaml, close_in ic; List.rev !matched_lines is grouped into a subexpression of "with" keyword, so its type should match with "try" expression. I try to find ways to break the relation between close_in ic; and List.rev !matched_lines, but failed.
You can use begin/end or parentheses:
let match_file pattern file_name =
let matched_lines = ref [] in
let ic = open_in file_name in
begin
try
while true
do
let line = input_line ic in
if (Str.string_match (Str.regexp pattern) line 0)
then
matched_lines := line::!matched_lines
done
with End_of_file -> close_in ic
end;
List.rev !matched_lines
The type of the loop is unit even though it never complete. The typechecker doesn't know that, so you need to make the expression under try have the same type as the exception handlers.
In this case you could use an arbitrary list such as [] but it's misleading for the reader, and doesn't generalize to cases where it may be more complicated to provide an expression of the correct type.
The idiomatic solution here is to place an assert false, which would raise an exception if ever evaluated. Unlike the infinite while loop, assert false is known by the typechecker to not return and it is compatible with any type since a value is never produced:
try
while true do
...
done;
assert false
with ... -> ...
Your code is just fine:
one semicolon after done, for sequencing of instructions, and then !matched_lines as return value of the try code part, then with ....
No ambiguities here. The compiler just doesn't take into account that End_of_file is always raised.
The rest is question of coding style. I like putting a (* never reached *) comment at these technically required expressions - would be a good idea for the assert false proposal as well IMO.

Compound Boolean Expr: Void Value Expression

def success?
return #fhosts.empty? and #khosts.empty? and #shosts.any?
end
When I run that instance method, I get an error:
/home/fandingo/code/management/lib/ht.rb:37: void value expression
return #fhosts.empty? and #khosts.empty? and #shosts.any?
I'm confused by what's happening since this works
def success?
#fhosts.empty? and #khosts.empty? and #shosts.any?
# This also works
# r = #fhosts.empty? and #khosts.empty? and #shosts.any?
# return r
end
I'm coming from a Python background, and I don't want anything to do with implicit returns. Programming has plenty of landmines as it is.
If we have an arbitrary expression, E, that consists of boolean operations and and or together, here are some operations we could perform:
if E -- works
E -- works
* v = E -- works
return E -- broken
Why doesn't the last case work?
Edit: Actually v = E doesn't work. Only
v = Ei
is evaluated. Ei+1...k are ignored.
This is likely due to the very weak binding of and which causes it to parse out differently than you expect:
return x and y
This actually means:
(return x) and y
Since you're returning immediately it doesn't have a chance to evaluate the remainder of the expression.
Your version without return is correct:
x and y
This doesn't have a binding issue and is more idiomatic Ruby. Remember you only need to put an explicit return if you're trying to force an exit before the last line of the method. Being opposed to implicit returns is going to make your code look heavily non-Ruby. They're one of the reasons Ruby is so clean and simple, and how things like a.map { |v| v * 2 } works.
The When in Rome principle applies here. If you want to write Python-style Ruby you're going to be going against the grain. It's like saying "I don't like how you say X in your spoken language, so I'll just ignore that and do it my way."
This should also work:
return x && y
The && method is very strongly bound so return is the last thing evaluated here.
Or if you really want to use and for whatever reason:
return (x and y)

Do "Ors" Evaluate The Whole Expression?

Say I have the following statement logic (I'll be using VBA for this example, but it also pertains to other languages)
x = 1
y = 2
z = 1000
If x = 1 Or y = 2 Or z = 4 Then
Execute Code
End
Does the compiler or executing program find that the first value is true, and then continue to Execute Code or does it finish off the rest of the statement?
I can't speak for VBA, but I can say that it is language specific. In some languages, the programmer has the ability to use "short-circuit" AND and OR expressions. Short-circuiting is the process of no longer evaluating a boolean expression if the result has already been determined.
If using a short-circuited AND, the boolean operation stops early if a FALSE is found. If using a short-circuited OR, the boolean operation stops early if a TRUE is found.
For example, in Java:
a || b is a short-circuited OR
a | b is a non-short-circuited OR
a && b is a short-circuited AND
a & b is a non-short-circuited AND
Some may ask, "why would I ever use a non-short-circuited AND or OR?" The reason for this comes when you are calling a function that returns a boolean that you want to run in every case. For example a() | b() would run both function a and function b. a() || b() only runs function b if a returns false.
I think that also in vba you can use OrElse.
'Or' (bitwise comparison) always finishes the rest of the statement, 'OrElse' (logical comparison) stops when the requirement is met.
In C++, C# and Java you can use '|' and '||'.
For example if object is null Or object.value = "" will result in a null exception when the object is empty because of the attempt to access a field from an empty object.
With OrElse the evaluation if object is null OrElse object.value = "" will stop at the first comparison when an empty object is evaluated.

Resources