Hiding an operator in Ada while still using it in the package body - operators

I need guidance on hiding an operator in Ada, while still calling it from the package body where the type was declared.
I have a type within a package where a few of the intrinsic operators are hidden by marking the operator definition as abstract, because semantically it's nonsense. However I still need the operators in the body, so that other operations can be calculated more efficiently than their workarounds. Is there a way to mark the operator as not abstract within the body, even though it is abstract in the spec? Or would I need to declare a new, equivalent function, and import from Intrinsics?
The operators in question are * and /.

I don’t believe you can "mark the operator as not abstract within the body".
A reasonably neat way of re-importing the intrinsic would be
package Abstracting is
type T is new Integer;
function "+" (L, R : T) return T is abstract;
function Add (L, R : T) return T;
end Abstracting;
(I’m making a guess about your actual type - it has to be visibly numeric, or "+", "/" wouldn’t be a problem in the first place).
Then,
package body Abstracting is
package Intrinsics is
function "+" (L, R : T) return T with Import, Convention => Intrinsic;
end Intrinsics;
OK, that re-imports "+". Now make it visible:
use Intrinsics;
function Add (L, R : T) return T is
begin
return L + R;
uses the version of "+" from package Intrinsics (I tried putting the use inside Add but it didn’t work. Must be treading pretty close to the edge here :)
end Add;
end Abstracting;

Typically one makes the public definition private and only declares the operations that are meaningful to the abstraction. This leaves the undefined but intrinsic operations of the full type available in the body:
package P is
type T is private;
function "+" (Left : T; Right : T) return T;
function "-" (Left : T; Right : T) return T;
private -- P
type T is range ...;
end P;
The difficulty with this approach is not with using the undefined operations but when you need to use the intrinsic operations that you've overridden: "+" and "-" in this case. This is usually solved by deriving T, converting values to the parent type to perform the operations, and converting back to T:
private -- P
type Raw is range ...;
type T is new Raw;
end P;
Then you can use "+" and "-" for Raw in the pkg body:
function "+" (Left : T; Right : T) return T is
(T (Raw (Left) + Raw (Right) ) );

Related

How to (force) overloading of plus for integers in Kotlin?

I would like to make plus mean something else, than addition. For example, creation of lazy expressions for computational graph. Unfortunately, class extensions cant override member functions. The following code will print 3:
operator fun Int.plus(other: Int) = listOf(this, other)
fun main() {
println( 1 + 2 )
}
Is is possible to force overriding?
No it is not possible. 1 + 2 is lowered into 1.plus(2), and there is a well defined order in how the compiler finds an appropriate plus method. Specification:
If a call is correct, for a callable f with an explicit receiver e
of type T the following sets are analyzed (in the given order):
Non-extension member callables named f of type T;
Extension callables named f, whose receiver type U conforms to type T, in the current scope and its upwards-linked scopes, ordered
by the size of the scope (smallest first), excluding the package
scope;
[...]
[...]
When analyzing these sets, the first set which contains any
applicable callable is picked for c-level partition, which gives us
the resulting overload candidate set.
So the plus method that is declared in Int is always found first, and the search stops there. Any extension you define will be ignored.
Hypothetically, if the built-in Int.plus is an implicitly imported extension function, then your code would have worked! Implicitly imported extensions are #6 on that list :)
My workaround for this situation is to use the "declare functions with almost any name by adding backticks" feature:
infix fun Int.`+`(other: Int) = listOf(this, other)
fun main() {
println( 1 `+` 2 )
}
This wouldn't work for some names that have reserved characters like square brackets, angle brackets, slashes, and dot (not an exhaustive list).

How do I read / interpret this Kotlin code effectively?

I know how to read/interpret Java code and I can write it. However being new to kotlin I find code like below hard to read. Perhaps I am missing key concepts in the language.
But, how would you go about interpreting this code? Where do you propose one to start reading it in order to understand this piece of code quickly and efficiently? Left to right? Right to left? Break down parameters first? Look at return values?
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
return input?.let(callback)
}
So, like Java this is a generic function. It has two type parameters T which is of type 'Any' ('Any' is like 'Object' in Java) and R. The input parameter is a nullable T, as denoted by the question mark. Nullable types mean that the value can be null. The other function parameter is a function that takes in a T (non nullable type) and returns R. The return type of the function is a nullable R. The body of the function says that if input is not null, call and pass that to the callback and return that value. If input is null, then null is what gets returned.
Let's dissect the function definition piece by piece:
inline: Indicates that the code of the function will be copied directly to the call site, rather than being called like a normal function.
fun: We're defining a function.
<T : Any, R>: The function takes two generic type parameters, T and R. The T type is restricted to the Any type (which is Kotlin's Object-type). That might seem redundant, but what it actually says is that T cannot be a nullable type (Any?).
ifNotNull: The name of the function.
input: T?: The first parameter of type T?. We can put the ? on the T type here because we restricted it to non-nullable types in the type declaration.
callback: (T) -> R: The second parameter is of type (T) -> R, which is a function type. It's the type of a function that takes a T as input and returns an R.
: R?: The function returns a value of type R or null.
return input?.let(callback): The function body. The let function takes a function parameter, calls it with its receiver (input), and then returns the result of the function. The ? after input says that let will be called only if input is not null. If input is null, then the expression will return null.
The function is equivalent to this Java method (except for the inlining and nullable types):
public <T, R> R ifNotNull(final T input, final Function<T, R> callback) {
if (input == null) {
return null;
}
return callback.apply(input);
}
Matt's answer explains everything well in one go; I'll try to look at how you might go about reading such code.
Skipping over the first word for now, the most important thing is the second word: fun.  So the whole thing is defining a function.  That tells you what to expect from the rest.
The braces tell you that it's a block function, not a one-liner, so the basic structure you're expecting is: fun name(params): returnType { code }.  The rest is filling in the blanks!  (This fits the general pattern of Kotlin declarations, where the type comes second, after a colon.  The Java equivalent would of course be more like returnType name(params) { code }.)
As with Java, the stuff in angle brackets is giving generic parameters, so we can skip that for now and go straight to the next most important bit, which is the name of the function being defined: ifNotNull.
Armed with those, we can read the rest.  inline is a simple modifier, telling you that the function will be inlined by the compiler.  (That enables a few things and restricts a few others, but I wouldn't worry about that now.)
The <T : Any, R> gives the generic parameter types that the function uses.  The first is T, which must be Any or a subtype; the second is R, which is unrestricted.
(Any is like Java's Object, but can't be null; the topmost type is the related Any?, which also allows null.  So except for the nullability, that's equivalent to the Java <T extends Object, R>.)
Going on, we have the function parameters in parentheses.  Again, there are two: the first is called input, and it's of type T?, which means it accepts any value of type T, and also accepts null.  The second parameter is called callback, and has a more complicated type, (T) -> R: it's a function which takes a T as its parameter, and returns an R.  (Java doesn't have function types as such, so that probably looks strangest.  Java's nearest equivalent is Function<R, T>.)
After the parentheses comes the return type of this function itself, R?, which means it can return either an R or null.
Finally, in braces is the actual code of the function.  That has one line, which returns the value of an expression.  (Its effect is to check whether the value of input is null: if so, it returns the null directly.  Otherwise, it calls the callback function given in the parameter, passing input as its parameter, and returns its result.)
Although that's a short declaration, it's quite abstract and packs a lot in, so it's no wonder you're finding it hard going!  (The format is similar to a Java method declaration — but Kotlin's quite expressive, so equivalent code tends to be quite a bit shorter than Java.  And the generics make it more complex.)  If you're just starting to learn Kotlin, I'd suggest something a bit easier :-)
(The good news is that, as in Java, you don't often need to read the stdlib code.  Although Kotlin's doc comments are rarely up to the exemplary level of Java's, they're still usually enough.)

'How to use higher order functors properly?' or 'How to have serious fun with funsigs?'

Motivation
For the life of me, I cannot figure out how to use higher order functors in
SML/NJ to any practical end.
According to the
SML/NJ docs on the implementation's special features,
it should be possible to specify one functor as an argument to another by use of
the funsig keyword. Thus, given a signature
signature SIG = sig ... end
we should be able to specify a functor that will produce a module satisfying
SIG, when applied to a structure satisfying some signature SIG'. E.g.,
funsig Fn (S:SIG') = SIG
With Fn declared in this way, we should then (be able to define another
functor that takes this functor as an argument. I.e., we can define a module
that is parameterized over another parameterized module, and presumably use the
latter within the former; thus:
functor Fn' (functor Fn:SIG) =
struct
...
structure S' = Fn (S:SIG')
...
end
It all looks good in theory, but I can't figure out how to actually make use of
this pattern.
Example Problems
Here are two instances where I've tried to use this pattern, only to find
it impracticable:
First attempt
For my first attempt, just playing around, I tried to make a functor that would
take a functor implementing an ordered set, and produce a module for dealing
with sets of integers (not really useful, but it would let you parameterize sets
of a given type over different set implementations). I can define the
following structures, and they will compile (using Standard ML of New Jersey
v110.7):
structure IntOrdKey : ORD_KEY
= struct
type ord_key = int
val compare = Int.compare
end
funsig SET_FN (KEY:ORD_KEY) = ORD_SET
functor IntSetFn (functor SetFn:SET_FN) =
struct
structure Set = SetFn (IntOrdKey)
end
But when I actually try to apply IntSetFn to a functor that should satisfy the
SET_FN funsig, it just doesn't parse:
- structure IntSet = IntSetFn (functor ListSetFn);
= ;
= ;;
stdIn:18.1-24.2 Error: syntax error: deleting RPAREN SEMICOLON SEMICOLON
- structure IntSet = IntSetFn (functor BinarySetFn) ;
= ;
= ;
stdIn:19.1-26.2 Error: syntax error: deleting RPAREN SEMICOLON SEMICOLON
Second attempt
My second attempt fails in two ways.
I have defined a structure of nested modules implementing polymorphic and
monomorphic stacks (the source file, for the curious). To
implement a monomorphic stack, you do
- structure IntStack = Collect.Stack.Mono (type elem = int);
structure IntStack : MONO_STACK?
- IntStack.push(1, IntStack.empty);
val it = - : IntStack.t
and so forth. It seems to work fine so far. Now, I want to define a module that
parameterizes over this functor. So I have defined a funsig for the
Collect.Stack.Mono functor (which can be seen in my repo). Then, following the
pattern indicated above, I tried to define the following test module:
(* load my little utility library *)
CM.autoload("../../../utils/sources.cm");
functor T (functor StackFn:MONO_STACK) =
struct
structure S = StackFn (type elem = int)
val x = S.push (1, S.empty)
end
But this won't compile! I get a type error:
Error: operator and operand don't agree [overload conflict]
operator domain: S.elem * S.t
operand: [int ty] * S.t
in expression:
S.push (1,S.empty)
uncaught exception Error
raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
../compiler/TopLevel/interact/evalloop.sml:44.55
../compiler/TopLevel/interact/evalloop.sml:292.17-292.20
Yet, inside functor T, I appear to be using the exact same instantiation
pattern that works perfectly at the top level. What am I missing?
Unfortunately, that's not the end of my mishaps. Now, I remove the line
causing the type error, leaving,
functor T (functor StackFn:MONO_STACK) =
struct
structure S = StackFn (type elem = int)
end
This compiles fine:
[scanning ../../../utils/sources.cm]
val it = true : bool
[autoloading]
[autoloading done]
functor T(<param>: sig functor StackFn : <fctsig> end) :
sig
structure S : <sig>
end
val it = () : unit
But I cannot actually instantiate the module! Apparently the path access syntax
is unsupported for higher order functors?
- structure Test = T (functor Collect.Stack.Mono);
stdIn:43.36-43.43 Error: syntax error: deleting DOT ID DOT
I am at a lost.
Questions
I have three related questions:
Is there a basic principle of higher-order functors in SML/NJ that I'm
missing, or is it just an incompletely, awkwardly implemented feature of the
language?
If the latter, where can I turn for more elegant and practicable higher order
functors? (Hopefully an SML, but I'll dip into OCaml if necessary.)
Is there perhaps a different approach I should taking to achieve these kinds
of effects that avoids higher order functors all together?
Many thanks in advance for any answers, hints, or followup questions!
Regarding your first attempt, the right syntax to apply your IntSetFn functor is:
structure IntSet = IntSetFn (functor SetFn = ListSetFn)
The same applies to your application of the Test functor in the second attempt:
structure Test = T (functor StackFn = Collect.Stack.Mono)
That should fix the syntax errors.
The type error you get when trying to use your stack structure S inside functor T has to do with the way you defined the MONO_STACK funsig:
funsig MONO_STACK (E:ELEM) = MONO_STACK
This just says that it returns a MONO_STACK structure, with a fully abstract elem type. It does not say that its elem type is gonna be the same as E.elem. According to that, I would able to pass in a functor like
functor F (E : ELEM) = struct type elem = unit ... end
to your functor T. Hence, inside T, the type system is not allowed to assume that type S.elem = int, and consequently you get a type error.
To fix this, you need to refine the MONO_STACK funsig as follows:
funsig MONO_STACK (E:ELEM) = MONO_STACK where type elem = E.elem
That should eliminate the type error.
[Edit]
As for your questions:
Higher-order functors are a little awkward syntactically in SML/NJ because it tries to stay 100% compatible with plain SML, which separates the namespace of functors from that for structures. If that wasn't the case then there wouldn't be the need for funsigs as a separate namespace either (and other syntactic baroqueness), and the language of signatures could simply be extended to include functor types.
Moscow ML is another SML dialect with a higher-order module extension that resolves the compatibility issue somewhat more elegantly (and is more expressive). There also was (now mostly dead) ALice ML, yet another SML dialect with higher-order functors that simply dropped the awkward namespace separation. OCaml of course did not have this constraint in the first place, so its higher-order modules are also more regular syntactically.
The approach seems fine.

Object-oriented programming in Go -- use "new" keyword or nah?

I am learning Go, and I have a question based on the following code:
package main
import (
"fmt"
)
type Vector struct {
x, y, z int
}
func VectorFactory(x,y,z int) *Vector {
return &Vector{x, y, z}
}
func main() {
vect := VectorFactory(1, 2, 3)
fmt.Printf("%d\n", (vect.x * vect.y * vect.z))
}
Here I've defined a type Vector with x, y, and z, and I've defined function VectorFactory which declares a pointer to a Vector and returns that pointer. I use this function to create a new Vector named vect.
Is this bad code? Should I be using the new keyword rather than building a Factory?
Do I need to delete the Vector after using it, like in C++? If so, how?
Thanks. I'm still waiting for my Go book to be delivered.
Prefer NewThing to ThingFactory.
Don't make a NewThing function, unless you have complex initialisation, or you're intentionally not exporting parts of a struct. Selectively setting only parts of a struct is not complex, that can be accomplished by using labels. Complex would be things like "the value of slot Q depends on what the value of slot Zorb is". Unexported struct fields can be useful for information hiding, but should be used with care.
Go is garbage-collected, any piece of data that is not referenced is eligible to be collected. Start out y not worrying about it, then get to a point where you ensure you clean up any reference to data you're no longer interested in so as to avoid accidental liveness ("accidental liveness" is essentially the GC equivalent of "memory leak").
If you expect to print your data structures frequently, consider making a String method for them (this is not exactly corresponding to the print you do, but might be generally more useful for a vector):
func (v Vector) String() string {
return fmt.Sprintf("V<%d, %d, %d>", v.x v.y, v.z);
}
Unless "vect" really means something to you, prefer either "v" or "vector" as a name.

SML/NJ: How to use HashTable?

I really want to create a HashTable in SML, it seems there already is a structure for this in SML/NJ.
The question is, how do I use it? I've not fully understood how to use structures in SML, and some of the very basic examples in the book I read gives me errors I don't even know how to correct, so using the HashTable structure might be an easy thing, but I wouldn't know. If someone could explain this, then that'd be wonderful too!
I'm thinking it's something like this:
val ht : string * int HashTable.hash_table = HashTable.mkTable();
???
The signature of the mkTable value is:
val mkTable : (('a -> word) * (('a * 'a) -> bool)) -> (int * exn)
-> ('a,'b) hash_table
(* Given a hashing function and an equality predicate, create a new table;
* the int is a size hint and the exception is to be raised by find.
*)
Therefore, you would have to do something like:
val ht : (string, int) HashTable.hash_table =
HashTable.mkTable (HashString.hashString, op=) (42, Fail "not found")
I assume the idea is to create a table mapping strings to integers. Then you want to write its type as (string, int) hash_table (the type hash_table is a type with two parameters, which are written like that in ML).
But you also need a hash function hash : string -> word and an equality function eq : string * string -> bool over strings to provide to mkTable. For the latter, you can simply use op=, for the former you can use HashString.hashString from the respective module.
So,
val ht : (string, int) HashTable.hash_table = HashTable.mkTable(HashString.hashString, op=)(17, Domain)
should work.
I should note, however, that hash tables tend to be vastly overused, and more often than not they are the wrong data structure. This is especially true in functional programming, since they are a stateful data structure. Usually you are better off (and potentially even more efficient) using some tree-based map, e.g., the RedBlackMapFn from the SML/NJ library.