Any Type Considered Harmful/en

Aus expecco Wiki (Version 2.x)
Version vom 29. August 2018, 14:15 Uhr von Cg (Diskussion | Beiträge) (→‎Do Not Be Lazy with the Output-Type)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

"Any"-Type Considered Harmful[Bearbeiten]

Output Pins with Any Type[Bearbeiten]

Do not be Lazy with the Output-Type[Bearbeiten]

Defining an output-pin to have "Any"-Type is a very common (beginners) mistake in expecco. The problem with this pin type is that it can only be connected to an input-pin which has a similar generality (i.e. either "Any" or "Object"), but not to more specific input pins. Especially not to most of the useful blocks from the standard library.

Here is an example, to make this more concrete:

Let us assume, that you have written a fancy and useful action block to measure the current temperature and sends it (a Number) to its temp output pin:

AnyConsideredHarmful example1.png

and, although the block will effectively only write numbers to this temp pin, it has been declared as "Any" (because we were to lazy and in a hurry to think about its implications). Now, assume that you need to further process the temperature value; for example, subtract a base-temperature. An obvious choice is to use a "Subtract" block from the standard library, which is defined as:

AnyConsideredHarmful example2.png

and connect it in your network:

AnyConsideredHarmful example3.png

but wait, the connection is not allowed, because the "Any"-output is more general than the "Number" input pin. Of course, you can force the connection (by pressing the Ctrl-key while connecting), to get:

AnyConsideredHarmful example4.png

The connection is now made, but with the type-check explicitly turned off (that is why the connection is shown as a dashed line). You can turn this into a solid line via the "Disable Type Check" context menu item (of the connection). That is a very ugly workaround: disabling the type checks is considered bad style, opening the door to many subtle errors.

So, in this particular example, you should define the output pin as what it is: Float (or maybe Integer, if your temperature comes in as integral value from the interface). So your block should definitely look like:

AnyConsideredHarmful example1Fixed.png

If the badly defined temperature block comes from another library, where you do not have control over its definition, a compromise is to add a checking cast block:

AnyConsideredHarmful example5.png

This will give you at least an error, in case any non-Float value ever appears.

But What if there Can be Really be Any Value? (Template Types)[Bearbeiten]

The above example was obvious, as the datum's type was actually Number and we were simply too lazy to define it correctly. But what shall we do, if an output's data can really be "Anything"?. For example, the following block delays its input value for a while, then passes it on to its output:

AnyConsideredHarmful example2 1.png

and code:

   execute
       |val|
       val := in value.
       Delay waitForSeconds:1.
       out value:val.

its input value can certainly be anything, so the output will also.

Well, no!

First, the output values will have the same type as the input values. Also, the input values come from some other block, so its output type determines what kind of values are appearing. Therefore, the correct type definition is by a Template Type, which means "the output has the same type as the input" and which automatically adapts to whatever it is connected to. As they should be unified to the same connected-type, each of the input and output pins should be of the same template type, '#1':

AnyConsideredHarmful example2 2.png

it can now be used in any other context; for example, when fed from out temperature block, which delivers Floats, its output will automatically be bound to the Float type as well:

AnyConsideredHarmful example2 3.png

Frozen Input Pins with Any Type[Bearbeiten]

Be careful when freezing an input pin that has an Any type, without explicitly specifying the freeze value's type (i.e. when using the "Freeze" menu item instead of the "Freeze as Type" menu item.

In this case, expecco has to determine the freeze value's type from the entered string. Thus, if you enter 22 (without quotes), it will assume that you want to freeze the pin as an integer, if you enter '22' (with quotes) or "22" (with double quotes), it will assume that it shall freeze it as a string. In most situations, you will probably desire a string value, so quotes are usually required.

Be aware that you can even enter a valid Smalltalk expression, such as "10 factorial", "Float pi" or "10 sin" (all without quotes), to get the expression evaluated and the result be used as freeze value. This is especially useful to define more complicated objects as freeze value, such as collections, streams, vectors etc. However, if the expression contains an error, the editor will show a warning message and fall back to a string value.

For string-typed input pins or when "Freeze as Type String" is used, no quotes are needed - actually, the entered string is taken literally, and any quotes will be part of the freeze value (whereas they have to be doubled in the above Any-type situation).

Freeze Values: When do we need Quotes?[Bearbeiten]

Quotes around String-typed freeze values are needed iff the pin type is not String and if you freeze it with "Freeze" instead of "Freeze as Type". Then, expecco determines the value's type from the entered string, and for that, needs the quotes to decide between String, Number or Smalltalk expression.



Back to Datatypes

Back to Online Documentation



Copyright © 2014-2024 eXept Software AG