Does any dialect of Pascal allow a variable number of arguments? - language-features

This is a question for the older programmers.
Years ago, I encountered a dialect of Pascal which allowed a variable number of arguments, through some kind of extension.
Does anyone know of a current dialect of Pascal which allows a variable number of arguments?
Given that Pascal is not as popular as it used to be, I wouldn't be surprised if the answer is no.
BTW, it is more correct, isn't it, to say variable number of arguments, rather than parameters ?

No. The answer is based on the Pascal dialects that I have used; others may be different.
The reason is that Pascal pushes arguments onto the stack frame in order, so all arguments are accessed via a fixed offset from the stack pointer. C, by comparison, pushes arguments in reverse order, so defined parameters are at fixed offset, and you can access "extra" arguments via pointer arithmetic. I'll try some ASCII art:
Pascal C
---------------------
| extra arg |
--------------------- ---------------------
| 1st param | | 3rd param |
--------------------- ---------------------
| 2nd param | | 2nd param |
--------------------- ---------------------
SP -> | 3rd param | | 1st param |
--------------------- ---------------------
As for parameter versus argument: as I learned it, the function (method) defines its parameters, the caller passes arguments. That definition came, I believe, from a Fortran manual, so that should give you an idea of how old I am :-)

You can use optional arguments with delphi to get the same effect:
procedure Proc(const A: Integer; const B: Integer = 15);
Proc(10); // B = 15
Proc(20,30);
Or overloaded methods:
procedure Proc(const A: Integer); overload;
procedure Proc(const A,B: Integer); overload;
Proc(10); // Variant 1
Proc(20,30); // Variant 2
Or you can use a variable array for parameters:
procedure Message(const AMessage: string; const AArgs: array of const);
Message('Hello %s', [Name]);
Message('%s %s', [Greeting, Name]);

GNU-Pascal (gcc based) afaik maps 1:1 to C support. using function something(arg:pchar;...) like syntax
Delphi/Free Pascal has "array of const" support, which is a typesafe version, and a varargs directive for the C interfacing (D6 or D7+)

You are probably thinking of a library that was available for Turbo Pascal where they had a hack like this. My syntax is a bit a rusty for objects and descending from it.
type
TValue = object;
TInteger = object(TValue)
Value : Integer;
end
TString = object(TValue)
Value : String;
end
TParam = record
Value : TValue;
Param : TParam;
end;
TValue = object;
{ Definition of Function }
function Test (Arg : TParam);
{ Usage }
var
I : TInteger;
S : TString;
Test (TParam (I, TParam (S, nil));
You could just chain as many arguments as you wanted. The last one had to be terminated with nil.

Yes!
Use the params keyword:
procedure write(params args: array of Object);
begin
{...}
end;

Related

What is right part in "query : SelectionSet Response RootQuery" type annotations?

I try to understand this line:
query : SelectionSet Response RootQuery
I understand this is a "Type Annotations" syntax, but I don't find documentation example or explanation about multiple "word" separated by whitespace.
I see these examples:
answer : Int
factorial : Int -> Int
distance : { x : Float, y : Float } -> Float
add : number -> number -> number (ref)
I found anywhere query: Int Int Int syntax, neither in Elm Syntax nor in Beginning Elm nor in Elm FAQ.
Do SelectionSet, Response, RootQuery are
functions arguments?
multi value function results?
Best regards,
Stéphane
Same question on Elm Discourse
A response in How do I read the type of a SelectionSet?
SelectionSet is a type with two type variables. Here's the definition:
type SelectionSet decodesTo scope
= SelectionSet (List RawField) (Decoder decodesTo)
In a type declaration like this, any lowercase name after the type is a type variable, which can be filled in by any type (except for a few special constrained type variables, number, appendable, comparable, and compappend). A simpler example would be Maybe, where you can have a Maybe Int or a Maybe String. Similarly, Dict takes two type variables (for the key and value) so you can have Dict String String or Dict Int MyCustomType (the key type of a Dict does need to be comparable).
So, in your scenario, Response corresponds to decodesTo and RootQuery corresponds to scope. The SelectionSet has a Decoder that decodes to a Response value, and it also carries around this scope type variable, which isn't used directly in the data that it holds. It's used as a piece of information at the type level, so that you (and the library) know that calling map (which has the type (a -> b) -> SelectionSet a scope -> SelectionSet b scope) will preserve that scope value; that is, it prevents mixing scopes.
The above is mostly general function syntax for functional languages such as Haskell, Elm, etc.
For example:
add : Int -> Int -> Int
add x y = x + y
The first line says that is function of two integer arguments with an integer return value. The second line implements the specification given in the first. One calls this function as follows:
> add 2 3
5
Note this example:
> inc = add 1
> inc 2
3
Here add 1 is a "partially applied function." It has type Int -> Int. In many languages, add 1 would not make sense. But since functions are first-class things in Elm, add 1 makes sense: it is a function. Partial application is also called "currying."

Where can I learn about perl6 Type variables (::T)

I need to use perl6 type variables. It seems that the definitive manual is here http://www.jnthn.net/papers/2008-yapc-eu-perl6types.pdf, which is concise and v. useful in so far as it goes.
Is there anything more comprehensive or authoritative that I can be pointed to?
What you're referring to is called "type capture" in perl6, here's two pages about them:
Type Captures in function/method signatures: https://docs.perl6.org/type/Signature#index-entry-Type_Capture_%28signature%29
Type Captures in Roles: https://docs.perl6.org/language/typesystem#index-entry-Type_Capture_%28role%29
Hope that helps!
The way I like to think of it is that Int is really short for ::Int.
So most of the time that you are talking about a type, you can add the :: to the front of it.
Indeed if you have a string and you want to use it to get the type with the same short name you use ::(…)
my $type-name = 'Int';
say 42 ~~ ::($type-name); # True
The thing is that using a type in a signature is already used to indicate that the parameter is of that type.
-> Int $_ {…}
Any unsigiled identifier in a signature is seen as the above, so the following throws an error if there isn't a foo type.
-> foo {…}
What you probably want in the situation above is for foo to be a sigiless variable. So you have to add a \ to the front. (Inside of the block you just use foo.)
-> \foo {…}
So if you wanted to add a feature where you capture the type, you have to do something different than just use an identifier. So obviously adding :: to the front was chosen.
-> ::foo { say foo }
If you call it with the number 42, it will print (Int).
You can combine these
-> Real ::Type \Value {…}
The above only accepts a real number (all numerics except Complex), aliases the type to Type, and aliases the number to Value
sub example ( Real ::Type \Value ) {
my Type $var = Value;
say Type;
say Value;
}
> example 42;
(Int)
42
> example ''
Type check failed in binding to parameter 'Value'; expected Real but got Str ("")
in block <unit> at <unknown file> line 1
> example 42e0
(Num)
42
This is also used in roles.
role Foo[ Real ::Type \Value ] {
has Type $.foo = Value; # constrained to the same type as Value
}
class Example does Foo[42] {}
say Example.new( :foo(128) ).foo; # 128
say Example.new().foo; # 42
say Example.new( :foo(1e0) ); # Type check error
You can of course leave off any part that you don't need.
role Foo[::Type] {…}

Equivalent of creating objects in Haskell

I am trying to understand how the following are used:
data Maybe a = Nothing | Just a
data Either a b = Left a | Right b
From my understanding these are parameterized algebraic data types. Coming from an OO background, I would now like to create an instance of these objects. If I do something like:
x = Maybe 10
Is that now a subclass/sub-algebraic-data-type, or wondering what that object is called. I would assume it is a type of some sort. If so, then I am wondering how to create an instance of x. In OO land I would do:
myinstance = new x
This is where coming to Haskell gets me lost and I'm not sure where to search. A few questions to summarize:
What kind of object x is above. If Maybe is a parameterized data type, then x is ~something~ type, not sure.
How to create an instance of x.
What is the instance of x for Maybe, since we passed it 10. Wondering, if the instance value is 10 and has type Int.
There is no such thing as Maybe 10 in Haskell. There is Maybe Int, which is a type.
We create a value of a certain type, directly, as
x :: Maybe Int
x = Just 10
or
y :: Maybe Int
y = Nothing
Simple and direct.
edit: Maybe is a type constructor. Just and Nothing are data constructors. By writing Maybe Int we "create" a type. There can't be a definition z :: Maybe ; z = ......
This is known as "kind": the kind of Maybe is * -> *, while e.g. Int's is * and so is Maybe Int's. Try :k at GHCi prompt to see this:
~> :k Int
Int :: *
~> :k Maybe
Maybe :: * -> *
~> :k Maybe Int
Maybe Int :: *
Of course we don't actually create a new type when we write "Maybe Int, it's just that Maybe by itself is not a type of things yet (types of "things" have kind *).
The definition for Maybe is what creates the types Maybe a, for any a we might use. This is known as parametric polymorphism.
So in Haskell, we don't have objects (in the OOP sense). We have values and types.
What kind of object x is above. If Maybe is a parameterized data type, then x is ~something~ type, not sure.
You can not construct a Maybe 10, you can for example construct a Just 10. In case 10 is here an Int (well technically it can be any numerical type, but let us ignore that for now), then you constructed a Maybe Int.
Note that a in Maybe a, is one meta level higher: it works with types. Hence a is a type parameter. It thus does not take as value 10, but for example Int.
What you can do however is define a type alias for Maybe Int, for example:
type X = Maybe Int
Note that we here use type as a type alias, not data to construct a data type.
Types (and type aliasses) always start with an upper case, so we can not define a type x, only a type X. A type has no default constructor (which is typically the case in OO programming languages).
How to create an instance of x.
Haskell can derive the most generic type of an expression itself. We thus write an expression that has the type of Maybe Int, so for example
Just 10
In case the type would be too generic (here it will be Num a => Maybe a), we can give a hint to Haskell by using two consecutive colons (::), for eample:
Just 10 :: Maybe Int
or since we already introduced the type alias X:
Just 10 :: X
What is the instance of x for Maybe, since we passed it 10. Wondering, if the instance value is 10 and has type Int.
Welll as said before, types in Haskell have no default constructor. We here have two candidates: Just n with n an Int (in case we use type X), or Nothing. So we pick one of the two:
Just 10 :: X
Nothing :: X
Since you can not change the state of an object anymore after you constructed it (i.e. all objects in Haskell are immutable), that means that it would be strange that a default constructor sets some initial data, and then later methods would change that object.
You can therefore see a data constructor (here Just and Nothing) as a labelled container that holds a group of parameters together in a container, and labels it with what constructor was used. So a graphical view of the objects would be:
+------+ +---------+
| Just | | Nothing |
+------+ +---------+
| o |
+---|--+
|
v
+----+
| 10 |
+----+
When you write an algebraic type definition as
data Maybe a = Nothing | Just a
the LHS is a type construction expression (it states that Maybe has kind * -> *), and the RHS is a disjunction of alternatives each one being a value constructor, so for type Maybe a, Just is an unary constructor that creates an object of this type, and Nothing is the nullary one.

What is "_," (underscore comma) in a Go declaration?

And I can't seem to understand this kind of variable declaration:
_, prs := m["example"]
What exactly is "_," doing and why have they declared a variable like this instead of
prs := m["example"]
(I found it as part of Go by Example: Maps)
It avoids having to declare all the variables for the returns values.
It is called the blank identifier.
As in:
_, y, _ := coord(p) // coord() returns three values; only interested in y coordinate
That way, you don't have to declare a variable you won't use: Go would not allow it. Instead, use '_' to ignore said variable.
(the other '_' use case is for import)
Since it discards the return value, it is helpful when you want to check only one of the returned values, as in "How to test key existence in a map?" shown in "Effective Go, map":
_, present := timeZone[tz]
To test for presence in the map without worrying about the actual value, you can use the blank identifier, a simple underscore (_).
The blank identifier can be assigned or declared with any value of any type, with the value discarded harmlessly.
For testing presence in a map, use the blank identifier in place of the usual variable for the value.
As Jsor adds in the comments:
"generally accepted standard" is to call the membership test variables "ok" (same for checking if a channel read was valid or not)
That allows you to combine it with test:
if _, err := os.Stat(path); os.IsNotExist(err) {
fmt.Printf("%s does not exist\n", path)
}
You would find it also in loop:
If you only need the second item in the range (the value), use the blank identifier, an underscore, to discard the first:
sum := 0
for _, value := range array {
sum += value
}
The Go compiler won't allow you to create variables that you never use.
for i, value := range x {
total += value
}
The above code will return an error message "i declared and not used".
Since we don't use i inside of our loop we need to change it to this:
for _, value := range x {
total += value
}
The blank identifier may be used whenever syntax requires a variable name but program logic does not, for instance to discard an unwanted loop index when we require only the element value.
Excerpt From:
The Go Programming Language (Addison-Wesley Professional Computing Series)
Brian W. Kernighan
This material may be protected by copyright.
_ is the blank identifier. Meaning the value it should be assigned is discarded.
Here it is the value of example key that is discarded. The second line of code would discard the presence boolean and store the value in prs.
So to only check the presence in the map, you can discard the value. This can be used to use a map as a set.
The great use case for the unused variable is the situation when you only need a partial output. In the example below we only need to print the value (state population).
package main
import (
"fmt"
)
func main() {
statePopulations := map[string]int{
"California": 39250017,
"Texas": 27862596,
"Florida": 20612439,
}
for _, v := range statePopulations {
fmt.Println(v)
}
}
It is called the blank identifier and it helps in cases where you wish to discard the value that is going to be returned and not reference it
Some places where we use it:
A function returns a value and you don't intend to use it in the
future
You want to iterate and need an i value that you will not be
using
Basically, _, known as the blank identifier. In GO we can't have variables that are not being used.
As an instance when you iterating through an array if you are using value := range you don't want a i value for iterating. But if you omit the i value it will return an error. But if you declare i and didn't use it, it will also return an error.
Therefore, that is the place where we have to use _,.
Also it is used when you don't want a function's return value in the future.
An unused variable is not allowed in Golang
If you were coming from other programming languages this might feel bit difficult to get used to this. But this results in more cleaner code. So by using a _ we are saying we know there is a variable there but we don't want to use it and telling the compiler that does not complain me about it. :)
_(underscore) in Golang is known as the Blank Identifier. Identifiers are the user-defined name of the program components used for the identification purpose. Golang has a special feature to define and use the unused variable using Blank Identifier. Unused variables are those variables that are defined by the user throughout the program but he/she never makes use of these variables.
Go compiler throws an error whenever it encounters a variable declared but not used. Now we can simply use the blank identifier and not declare any variable at all.
// Golang program to show the compiler
// throws an error if a variable is
// declared but not used
package main
import "fmt"
// Main function
func main() {
// calling the function
// function returns two values which are
// assigned to mul and div identifier
mul, div := mul_div(105, 7)
// only using the mul variable
// compiler will give an error
fmt.Println("105 x 7 = ", mul)
}
// function returning two
// values of integer type
func mul_div(n1 int, n2 int) (int, int) {
// returning the values
return n1 * n2, n1 / n2
}
Output
./prog.go:15:7: div declared and not used
Let’s make use of the Blank identifier to correct the above program. In place of div identifier just use the _ (underscore). It allows the compiler to ignore declared and not used error for that particular variable.
// Golang program to the use of Blank identifier
package main
import "fmt"
// Main function
func main() {
// calling the function
// function returns two values which are
// assigned to mul and blank identifier
mul, _ := mul_div(105, 7)
// only using the mul variable
fmt.Println("105 x 7 = ", mul)
}
// function returning two
// values of integer type
func mul_div(n1 int, n2 int) (int, int) {
// returning the values
return n1 * n2, n1 / n2
}
Output
105 x 7 = 735

Error: Cannot safely evaluate the definition of the recursively-defined module

I'm curious to understand why this error happens and which is the best way to get around it.
I have a couple of files types.ml and types.mli which define a variant type value that can be of many different builtin OCaml types (float, int, list, map, set, etc..).
Since I have to use the std-lib over this variant type I needed to concretize the Set module through the functor to be able to use sets of value type by defining the ValueSet module.
The final .ml file is something like:
module rec I :
sig
type value =
Nil
| Int of int
| Float of float
| Complex of Complex.t
| String of string
| List of (value list) ref
| Array of value array
| Map of (value, value) Hashtbl.t
| Set of ValueSet.t ref
| Stack of value Stack.t
...
type t = value
val compare : t -> t -> int
end
= struct
(* same variant type *)
and string_value v =
match v with
(* other cases *)
| Set l -> sprintf "{%s} : set" (ValueSet.fold (fun i v -> v^(string_value i)^" ") !l "")
end
and OrderedValue :
sig
type t = I.value
val compare : t -> t -> int
end
= struct
type t = I.value
let compare = Pervasives.compare
end
and ValueSet : Set.S with type elt = I.value = Set.Make(I)
As you can see I had to define the ValueSet module from the functor to be able to use that datatype. The problem occurs when I want to use that module inside the declaration of I. So that I obtain the following error:
Error: Cannot safely evaluate the definition of the recursively-defined module I
Why does this happen? Which is a good way to solve it? And just to know, is my approach to what I'm trying to do correct? Apart from that it works as intended (I'm able to use the ValueSet type with my operations in other modules, but I have to comment the involved line in types.ml to pass compilation phase).
I tried to remove all the superfluous code and reduce the code to essential needed to investigate this error.. if it's not enought just ask :)
EDIT: according to OCaml reference we have that
Currently, the compiler requires that all dependency cycles between the recursively-defined module identifiers go through at least one “safe” module. A module is “safe” if all value definitions that it contains have function types typexpr1 -> typexpr2.
This is everything I found so far, but I don't get the exact meaning..
Thank in advance
After fixing the obvious errors, your example does compile (with OCaml 3.10, but I think this hasn't changed since recursive modules were introduced in 3.07). Hopefully my explanations below will help you find what, amongst the definitions you left out, caused your code to be rejected.
Here is some example code that is accepted:
module rec Value : sig
type t =
Nil
| Set of ValueSet.t
val compare : t -> t -> int
val nil : t
(*val f_empty : unit -> t*)
end
= struct
type t =
Nil
| Set of ValueSet.t
let compare = Pervasives.compare
let nil = Nil
(*let f_empty () = Set ValueSet.empty*)
end
and ValueSet : Set.S with type elt = Value.t = Set.Make(Value)
At the expression level, the module Value has no dependency on ValueSet. Therefore the compiler generates the code to initialize Value before the code to initialize Value, and all goes well.
Now try commenting out the definition of f_empty.
File "simple.ml", line 11, characters 2-200:
Cannot safely evaluate the definition of the recursively-defined module Value
Now Value does depend on ValueSet, and ValueSet always depends on Value because of the compare function. So they are mutually recursive, and the “safe module” condition must apply.
Currently, the compiler requires that all dependency cycles between the
recursively-defined module identifiers go through at least one "safe" module. A
module is "safe" if all value definitions that it contains have function types
typexpr_1 -> typexpr_2.
Here, ValueSet isn't safe because of ValueSet.empty, and Value isn't safe because of nil.
The reason to the “safe module” condition is the chosen implementation technique for recursive module:
Evaluation of a recursive module definition proceeds
by building initial values for the safe modules involved, binding all
(functional) values to fun _ -> raise Undefined_recursive_module. The defining
module expressions are then evaluated, and the initial values for the safe
modules are replaced by the values thus computed.
If you comment out the declaration of nil in the signature of Value, you can leave the definition and declaration of f_empty. That's because Value is now a safe module: it contains only functions. It's ok to leave the definition of nil in the implementation: the implementation of Value is not a safe module, but Value itself (which is its implementation coerced to a signature) is safe.
I'm really not sure what kind of syntax you're using in the signature that allows let ... I'm going to assume it was a mistake while reducing the code for us. You also don't need that OrderedType definition, possibly another fiddling error for us, since you don't use it in parameterisation of the Set module.
Aside from that, I have no problem running the following in the toplevel. Since this works pretty directly, I am unsure how you're getting that error.
module rec Value :
sig
type t =
| Nil
| Int of int
| Float of float
| String of string
| Set of ValueSet.t
val compare : t -> t -> int
val to_string : t -> string
end = struct
type t =
| Nil
| Int of int
| Float of float
| String of string
| Set of ValueSet.t
let compare = Pervasives.compare
let rec to_string = function
| Nil -> ""
| Int x -> string_of_int x
| Float x -> string_of_float x
| String x -> x
| Set l ->
Printf.sprintf "{%s} : set"
(ValueSet.fold (fun i v -> v^(to_string i)^" ") l "")
end
and ValueSet : Set.S with type elt = Value.t = Set.Make (Value)