What is the explanation that instances of Data1 and Data2 have different capabilities?
The line where an object of Data1 class is instantiated compiles without a problem, but the line with Data2 get's the error saying that "right side must be a subtype of left side".
class Data1
let _x: U8 = 0
class Data2
let _x: U8
new create() => _x = 0
actor Main
new create(env: Env) =>
let d1: Data1 iso = Data1
let d2: Data2 iso = Data2
In Pony, there are many places where you can omit basic elements of syntax or structure, and expect them to be filled in with implicit defaults. The answer to your question here about the difference between Data1 and Data2 has to do with two examples of implicit defaults, which happen to not have the same capability.
The Data2 class has a single constructor, new create() => _x = 0, which has a implicit default receiver capability of ref. That is, it implicitly expands to new ref create() => _x = 0.
The Data1 class has no constructor, so Pony creates an implicit default constructor for you, which is new iso create(). The _x = 0 from your field declaration also gets implicitly transferred to the body of the constructor, but that's somewhat outside the scope of your question.
So, in this case, assigning let d1: Data1 iso = Data1, since the created object will be of type Data1 iso^, which can be assigned to Data1 iso. Assigning let d2: Data2 iso = Data2 doesn't work, since the created object will be of type Data2 ref^, which can't be assigned to Data2 iso without breaking the isolation guarantees.
Changing your Data2 constructor to new iso create() is the best solution for making your example code work. We don't use iso as the implicit default capability for constructors because it would put additional constraints on the parameters to the constructor (they would all have to be sendable).
For completeness, note that there is another way around your problem, on the caller side. If you place the constructor call in a recover block, you can "lift" to a capability that has stronger guarantees (for example, from ref to iso). This works because the recover block enforces other constraints on object references used within it (for example, any references passing into the recover block must be sendable), that will uphold the guarantees you are lifting to. This assignment would look like:
let d2: Data2 iso = recover Data2 end
Related
I want to program a game and would like to use a component pattern for multiple entities.
In a language with interfaces / type-classes / multiple inheritance there would be no problem.
I want some entities to be updateable but not renderable and some shall be both.
Haskell:
class Updateable a where
update :: Float -> a -> a
class Renderable a where
render :: a -> Picture
class InputHandler a where
handleInput :: Event -> a -> a
I can create a list of things that can be updated.
updateAll :: Updateable a => Float -> [a] -> [a]
updateAll delta objs = map (update delta) objs
In Java/D/... this could be implemented via Interfaces
interface Updateable {
void update(float delta);
}
// somewhere in a method
List<Updateable> objs = ...;
for (Updateable o : objs) {
o.update(delta);
}
Now I am wondering how this can be implemented in nim with multimethods.
Can the existence of a fitting multimethod be expressed in a type?
var objs: seq[???] = #[]
Edit: Added more code and fixed incorrect Haskell example
I'm not sure if this answers your question, but it's worth mentioning.
If you were to store you game objects in separate lists based on type, you could still write a lot of generic logic. Storing objects by type has better better performance because of read-ahead and branch prediction. See this lecture, from a guy who should know what he's talking about: Multiprocessor Game Loops: Lessons from Uncharted 2: Among Thieves.
For instance, if you have defined a texture proc for some of your object types, then you can write a generic draw(t: T) = magicRenderToScreen(texture(t)) proc that will work for all of them. This is also useful if you are implementing resource pools, or any kind of general behaviour really.
You do have to include each affected object type in the render and update loops somehow, but that's usually not a big deal in practice. You can even use a simple macro to make this less verbose, so your render loop simply contains something like renderAll(players, enemies, sprites, tiles)
Generic lists are not straightforward in compiled languages, and nim forces you to see it, which is kind of good when you're working on a game. To have generic lists you typically either have to use pointers and dynamic dispatch, or some kind of union type. I seem to remember that nim used to be able to dispatch to the correct multi-methods from parent object ref's, (which would enable lists to contain several types and dispatch dynamically at runtime) but I'm honestly not sure if that can still be done...?
Someone more knowledgeable please let us know!
The lack of an explicit interface keyword is common question in the Nim community. Taking Araq's answer and applying it to a hypothetical case based on your Java/D snippet we could write something like this:
import strutils # For formatFloat
type
IUpdateable =
tuple[
update: proc(v: float) {.closure.},
show: proc(): string {.closure.}
]
Rounded = ref object
internalValue: float
Real = ref object
a_real_value: float
# Here goes our rounded type.
proc `$`(x: Rounded): string =
result = "Rounded{" & $int(x.internalValue) & "}"
proc updateRounded(x: Rounded, delta: float) =
x.internalValue += delta
proc getUpdateable(x: Rounded): IUpdateable =
result = (
update: proc(v: float) = x.updateRounded(v),
show: proc(): string = `$`(x)
)
converter toIUpdateable(x: Rounded): IUpdateable =
result = x.getUpdateable
# Here goes our Real type.
proc `$`(x: Real): string =
result = "Real{" &
x.a_real_value.format_float(precision = 3) & "}"
proc update_real(x: Real, delta: float) =
x.a_real_value += delta
proc getUpdateable(x: Real): IUpdateable =
result = (
update: proc(v: float) = x.update_real(v),
show: proc(): string = `$`(x)
)
# Here goes the usage
proc main() =
var objs: seq[IUpdateable] = #[]
var a = Rounded()
var b = Real()
a.internalValue = 3.5
b.a_real_value = 3.5
objs.add(a) # works because of toIUpdateable()
objs.add(b.getUpdateable)
for obj in objs:
echo "Going through one loop iteration"
echo "\t", obj.show()
obj.update(0.4)
echo "\t", obj.show()
obj.update(0.4)
echo "\t", obj.show()
main()
# -> Going through one loop iteration
# -> Rounded{3}
# -> Rounded{3}
# -> Rounded{4}
# -> Going through one loop iteration
# -> Real{3.50}
# -> Real{3.90}
# -> Real{4.30}
However, as you can read in that forum thread, depending on what exactly you need interfaces for other approaches may be better. Also, presumably the future way to go are concepts, but as usual the manual is dry and the related unit tests are cryptic so I couldn't manage to translate the previous tuple example to concepts.
If you feel like going for concepts you should ask in the forum directly, but beware, as the manual says, concepts are still in development.
Swift has the same problem and there they use Type Erasure, which is the same as proposed in the previous comments but a bit more strutured. The general pattern in Nim is like this:
#-------------------------------------------------------------
# types
#-------------------------------------------------------------
type C = concept type C
proc name(x: C, msg: string): string
type AnyC = object
name: proc(msg: string): string # doesn't contain C
type A = object
type B = object
#-------------------------------------------------------------
# procs
#-------------------------------------------------------------
proc name(x: A, msg: string): string = "A" & msg
proc name(x: B, msg: string): string = "B" & msg
proc name(x: AnyC, msg: string): string = x.name(msg) # AnyC implements C
proc to_any(x: A): AnyC = AnyC(
name: proc (msg: string): string = name(x, msg) # x captured by proc
)
proc to_any(x: B): AnyC = AnyC(
name: proc (msg: string): string = name(x, msg) # x captured by proc
)
# actually use C
proc print_name(x: C, msg: string) = echo x.name(msg)
#-------------------------------------------------------------
# main
#-------------------------------------------------------------
let a = A()
let b = B()
let cs = [a.to_any(), b.to_any()] # the main goal of most erasure cases
for c in cs:
c.print_name(" erased") # e.g. "A erased"
In this example AnyC implements C, A and B also implement C but more importantly can be converted to AnyC. The Any* types usually contain closures to effectively erase the type and also implement the concept itself by trivial forwarding the arguments.
I wish there was a macro or something that would implement Any* and to_any automatically.
I would like to do something like this (example is simplified, but contains all the crucial pieces):
class Master
{
type DataType = Int
var counter : DataType = 0
}
class Slave(private val master : Master)
{
val counter = master.counter // (*)
}
And here (*) I get error:
private value master escapes its defining scope as part of type
Slave.this.master.DataType
val counter = master.counter
I understand the error, but I don't understand the reason - the type is part of the class Master, not the object master, so it is important if the class is private, not an object. Well, at least in theory.
It is easy to make a quick workaround:
val counter : Master#DataType = master.counter
But I believe this is an explicit version of the exactly same code as before, it "only" takes more typing. Is this a feature then?
QUESTION:
Can a type (here DataType) be dependent of the object, and not the class (i.e. type definition per instance of the class) in Scala?
You are wrong when you think
this is an explicit version of the exactly same code as before
Master#DataType and master.DataType are two different types.
master.DataType is the type of those DataType instances which have master as outer object. In other words, precisely what you ask, but obviously then master is part of the type, and the type can't be exposed if master isn't.
Master#DataType is the type of any DataType instance for any outer object (equivalent to Master.DataType in Java).
REPLY TO THE COMMENT:
Type members can be overridden in a subclass (including an anonymous subclass containing only one object), but only by a compatible type. And in your example DataType is already concrete in Master, so the only compatible class with it is itself. So something like
val a = new Master {
override type DataType = String
}
won't typecheck, which makes sense: you'd get var counter: String = 0, which is nonsense. But
val a = new Master {
override type DataType = Int
}
will work (but isn't too useful).
So it only ever makes sense to override abstract type members. But they are type-checked in the same way as inner classes, so a.DataType is not generally considered the same as b.DataType -- even if they can't actually be different!
Sorry if the answer to this is obvious, but I want to be sure, if you have(in Python):
class Name(object):
def __init__(self):
self.int_att1 = 0
self.int_att2 = 0
self.list_att = []
why can't(I know you can, but I've never seen a programmer do this) you initialize it in this way:
class Name(object):
def __init__(self):
self.int_att1 = int
self.int_att2 = int
self.list_att = list
Are there bad effects that come out of this?
What makes the former more Pythonic?
My best guess is because Python needs a value for instance.attribute. But if this is the case than why is it that using datatype works?
When you do self.int_att1 = int, the attribute int_att1 now references to the type int, I mean, is just another name for int. And I'll prove this in a simple way:
>>> number_type = int
>>> i = number_type()
>>> i
0
>>> type(i)
<type 'int'>
In this code, number_type becomes a "synonym" for the type int, that's why when I asked the type of i, it returned int and not number_type.
Same for self.list_att = list.
Probably, what you wanted to do was:
class Name(object):
def __init__(self):
self.int_att1 = int()
self.int_att2 = int()
self.list_att = list()
This is totally different, you are not longer assigning the type to the attribute. Instead, you are assigning the initial value of that type. Let's see what those initial values are:
>>> initial_int = int()
>>> initial_int
0
>>> initial_list = list()
>>> initial_list
[]
So, we can clearly see that the initial value of the type int is 0 and the initial value of the type list is [], and that is exactly what you were looking for!
You can, but it has a totally different effect. In the second case, you're setting the attribute equal to the value of the type, which is usually not what you want. In Python types are objects too, so this is legal.
It would let you do something like:
n = Name()
v = n.int_att1()
v would then be 0, because that's the value constructed by int's no-arg constructor.
From The Zen of Python: "Explicit is better than implicit."
You could certainly initialize with the default value of a type (not the type itself as in your example), but explicit is better than implicit. When you initialize with an actual value, there's no doubt about what you're getting.
Edit: The bug which prompted this question has now been fixed.
In the Scala Reference, I can read (p. 86):
The interpretation of an assignment to
a simple variable x = e depends on the
definition of x. If x denotes a
mutable variable, then the assignment
changes the current value of x to be
the result of evaluating the
expression e. The type of e is
expected to conform to the type of x.
If x is a parameterless function
defined in some template, and the same
template contains a setter function
x_= as member, then the assignment x =
e is interpreted as the invocation
x_=(e) of that setter function.
Analogously, an assignment f .x = e to
a parameterless function x is
interpreted as the invocation f.x_=(e).
So, for instance, something like this works fine:
class A {
private var _a = 0
def a = _a
def a_=(a: Int) = _a = a
}
I can then write
val a = new A
a.a = 10
But if I define the class like this, adding a type parameter to method a:
class A {
private var _a = 0
def a[T] = _a
def a_=(a: Int) = _a = a
}
then it doesn't work any more; I get an error: reassignment to val if I write a.a = 10. Funny enough, it still works with no type parameter and an implicit parameter list, for instance.
Arguably, in this example, the type parameter is not very useful, but in the design of DSLs, it would be great to have the setter method called even if the getter has type parameters (and by the way, adding type parameters on the setter is allowed and works fine).
So I have three questions:
Is there a workaround?
Should the current behavior be considered a bug?
Why does the compiler enforce a getter method to allow using the syntactic sugar for the setter?
UPDATE
Here's what I'm really trying to do. It's rather long, sorry, I meant to avoid it but I realized it was more confusing to omit it.
I'm designing GUIs with SWT in Scala, and having huge fun using Dave Orme's XScalaWT, which immensely reduces the amount of needed code. Here's an example from his blog post on how to create an SWT Composite that converts °C to °F degrees:
var fahrenheit: Text = null
var celsius: Text = null
composite(
_.setLayout(new GridLayout(2, true)),
label("Fahrenheit"),
label("Celsius"),
text(fahrenheit = _),
text(celsius = _),
button(
"Fahrenheit => Celsius",
{e : SelectionEvent => celcius.setText((5.0/9.0) * (fahrenheit - 32)) }
),
button(
"Celsius -> Fahrenheit",
{e : SelectionEvent => fahrenheit.setText((9.0/5.0) * celsius + 32) })
)
)
The argument to each of the widget-constructing methods is of type (WidgetType => Any)*, with a few useful implicit conversions, which for instance allow to directly specify a string for widgets that have a setText() method. All constructor functions are imported from a singleton object.
In the end, I'd like to be able to write something along these lines:
val fieldEditable = new WritableValue // observable value
composite(
textField(
editable <=> fieldEditable,
editable = false
),
checkbox(
caption = "Editable",
selection <=> fieldEditable
)
)
This would bind the editable property of the textfield to the selection of the checkbox through the WritableValue variable.
First: named arguments are not applicable here, so the line editable = false has to come from somewhere. So, along the widget-constructing methods in the singleton object, I could write, conceptually,
def editable_=[T <: HasEditable](value: Boolean) = (subject: T) => subject.setEditable(value)
... but this works only if the getter is also present. Great: I'd need the getter anyway in order to implement databinding with <=>. Something like this:
def editable[T <: HasEditable] = new BindingMaker((widget: T) => SWTObservables.observeEditable(widget))
If this worked, life would be good because I can then define <=> in BindingMaker and I can use this nice syntax. But alas, the type parameter on the getter breaks the setter. Hence my original question: why would this simple type parameter affect whether the compiler decides to go ahead with the syntactic sugar for calling the setter?
I hope this makes it a bit clearer now. Thanks for reading…
UPDATE Deleted the entire previous answer in light of new information.
There's a lot of very odd stuff going on here, so I'm going try try and explain my understanding of what you have so far:
def editable_=[T <: HasEditable](value: Boolean) = (subject: T) => subject.setEditable(value)
This is a setter method, and exists purely so that it can give the appearance of beinng a named parameter
in your DSL. It sets nothing and actually returns a Function.
textField(
editable <=> fieldEditable,
editable = false
)
This is calling the textField factory method, with what looks like a named param, but is actually the setter method defined previously.
Amazingly, the approach seems to work, despite my initial concern that the compiler would recognize this as a named parameter and produce a syntax error. I tested it with simple monomorphic (non-generic) methods, though it does require the getter method to be defined for the setter to be seen as such - a fact that you've already noted.
Some amount of "cleverness" is often required in writing a DSL (where it would otherwise be totally forbidden), so it's no surprise that your original intent was unclear. This is perhaps a completely new technique never before seen in Scala. The rules for setter and getter definitions were based on using them as getters and setters, so don't be surprised if things crack a little when you push at the boundaries like this.
It seems the real problem here is the way you're using type params. In this expression:
def editable_=[T <: HasEditable](value: Boolean) = (subject: T) => subject.setEditable(value)
The compiler has no way of inferring a particular T from the supplied argument, so it will take the most general type allowed (HasEditable in this case). You could change this behaviour by explicitly supplying a type param when using the method, but that would seem to defeat the entire point of what you're seeking to achieve.
Given that functions can't be generic (only methods can), I doubt that you even want type bounds at all. So one approach you could try is to just drop them:
def editable_=(value: Boolean) = (subject: HasEditable) => subject.setEditable(value)
def editable = new BindingMaker((widget: HasEditable) => SWTObservables.observeEditable(widget))
Simple problem: I am subclassing a FilterInputStream in Scala, which has a read method:
public void read(byte [] b,int offset,int len)
The data being read will be put in b, but as parameters are "vals" in Scala methods, I see no way to properly subclass this. How do I set b to the data being read? The Java *InputStream really leaves me not much choice....
You can put an item into b at index i simply by doing b(i) = whatever. That b is a val doesn't have an effect on this. It just means that you can't reassign b (which wouldn't be useful to do anyway).
Just declaring something as a val instead of a var in Scala doesn't make it immutable. In fact, var can name an immutable value. The thing to remember is that variables in Scala, much like variables in Java, are always* references, or handles, rather than actually containing the value.
Try this in your REPL:
class Container { var content: String = "default" }
val a = new Container
val b = a
b.content = "modified"
println(a.content)
When you run val b = a you are making b and a names for the same thing (not a copy, the exact same instance of Container). Because of this, when you run b.content = "modified" the change is reflected in a as well; it is just another name for the same thing. Note this happens even though a is a val. All the val means is that you can't change what instance a is a name for.
Now think about this slight variation:
class Container { var content: String = "default" }
def update(c: Container) { c.content = "modified" }
val a = new Container
update(a)
println(a.content)
When you call update, its parameter c is also a reference or alias for a. So changes are reflected outside the method call the same way they are in the earlier example.
Arrays are mutable, so they work like this as well.
*: Primitive variables (bytes, doubles, ints, etc.) are not references in Java; their boxed equivalents (java.lang.Byte...) are. It doesn't show that much since these classes/types are immutable anyway.
def read(b: Array[Byte], offset: Int, len: Int): Unit
is equivanet to following in Java:
public void read(final byte[] b, final int offset, final int len)
The array b is still mutable, and you can modify its contents.