I’ve notice that in a number of threads in which a user asks a question about using blockly, the thread becomes a discussion about the implementation of blockly. I’ve created this thread as a place to discuss the subject with the community.
First, thank you Stefan for the HUGE amount of work you have done to implement blockly in openHAB. Thank you Yannick for quickly reviewing and introducing the improvements.
Next… To quote our illustrious Mr. Koshak ‘the uptake in Blockly use was breathtaking. It’s already very popular’. Argeed
First point of discussion: Yannick’s post here and Stefan’s post here
TL:DR Should blocks ’ provide some “good” reference code’ or be ‘black boxes - as a user, I don’t really care what’s in them as long as they do what I expect them to do’
personally I agree with Rich
Second point of discussion: Stefan’s question
As Kai states above, I would suspect most users will expect the blocks to ‘do what I expect them to do’
Well, I believe it was Einstein who said something about making something foolproof and the universe building bigger, better, and faster fools
My point is where do we draw the line between making the language bomb proof and fully functional? Is blockly another step toward making openHAB more user friendly to the non technical user? And if so, do we leave full functionality to the umteen million other (slight exaggeration) languages available and only implement blocks which have the best chance of not being abused?
I have a few other thoughts and hope others express their opinions on these and any other issues pertaining to the implementation of blockly in openHAB
Clean Code Generation
I wouldn’t want every basic operation to include a fool proof check to make absolutely sure it will work on the off chance it might be used improperly.
My rule of thumb is, look at how the standard blocks are implemented, and try to imitate that - if anything for consistency’s sake. There are already safeguards in place which are the type checks - i.e. you can make sure you can’t connect a block outputting a Number to a text manipulation block. The thing is, you can use variables to circumvent that because when you assign something to a variable you lose the type information. This IMHO doesn’t justify compensating this flaw with more code.
I just want to be clear that my big concern is not that it’s foolproof. By biggest concerns are that it’s consistent and intuitive to the users.
Blocks should do what they say and say what they do and shouldn’t break when used in a way that seems like they should. For example, in that other thread the “get state from item” block, intuitively seems like it should work if I pass it an Item Object. But it didn’t which is a surprise and counterintuitive.
But I do think there are opportunities where it can make sense to make blocks flexible. For example, why but make “get state from item” work with both the name or item Object? But given that eventually Blockly will move to using JSScripting and openhab-js, maybe it makes sense to wait on focusing too much on that and see what openhab-js provides. I expect a lot of the “foolproofing” well be implemented there.
But my original objection want l wasn’t about foolproofing. It was that the one particular block violated intuitive expectations. It’s name implies it gets the state from an Item where in fact it only gets the state of an Item given the name of that item.
It does seem like an opportunity for making Blockly much more user friendly to have that block work in both cases so that the one block works as expected in all the contexts where one needs to get the state of an Item (i.e. when one only has the name of the item, which is most of the time, or when one has the actual Item Object, like when iterating over the members of a Group).
Using an expression to handle both in that one block is not the only way to handle this. One could use a map operation to convert that list of Item Objects to a list of the item names and then the block will work consistently and intuitively.
Changing the names of the block can also work in some cases. If the name of the block makes it absolutely clear that it only accepts Item names and the block that iterates over members of a Group makes it absolutely clear it returns Item Objects. That too is acceptable.
But when a block says it gets the state from the Item but doesn’t, that’s a problem. Given the nature of OH, that’s probably not the only troublesome block, but it’s the first one to come to attention.
Just wanted to state that the reason I started this thread was because I believed it was bad forum etiquette to high jack another users question thread with a giant discussion about how blockly should be implemented.
Another observation I want to make is that some of these questions in the forum are not coming from complete newbies. The group handing thread was started by a user who has been here for three years. Another thread recently posted is by user hafniumzinc who has been here nearly two years and quite often pitches in helping answer questions here in the forum.
What I find particularly interesting about both these threads is that in both cases the user actually figured out how to ‘hack’ blockly and get it to work by basically fooling the interface.
You guys are playing to a pretty sophisticated audience
In what I thought would be a lot more typical of new user questions, the user in this thread is attempting to use the ‘store value’ block to be able to retrieve an item state that isn’t getting persisted during reboots… the block states ‘store value’
As Rick says
On another note, IMHO, I don’t think we should be afraid to rename a block to make more clear what it does
IF the USP for OH Blocky is simplicity, IMHO OH Blockly must be strongly typable (well, kind of …). One cannot expect from a beginner that she/he takes into account class hierarchy, polymorphism, overloading of operators, implicit typecasting etc. on the underlying layer.
Telling an OH Blockly user that there is a high probability that the result of get state of item is of type string doesn’t help at all - and introspection isn’t a concept a beginner is familiar with (let alone that there aren’t any corresponding blocks yet).
I would recommend providing blocks for explicit typecasting to ‘basic’ types: toString, toNumber, …
If unsure about the type of results of blocks, use explicit typecasting. If you know what you are doing, don’t use it.