How to scare a potential contributor off your project
-
I was thinking od contributing voice prompts in a new language for the OSMAnd project. The app, by the way, is one of the most useful things I've ever seen.
But then I've found out their voice configuration files are written in Prolog. The fuck. Now I would have to learn a whole new language to write a fucking config file.
So the recipe is: be a fucking basement dwelling geek. Make an otherwise good project, but masturbate your ego violently by putting your favourite toy/esoteric/niche language into a crucial part of it. Joke around about contributions being welcome.
-
This is relevant: http://tech.slashdot.org/story/15/03/30/2245223/why-you-should-choose-boring-technology
My choice of technology usually rests on the answer to the question "Can I easily get people to help me with this?". That's why I switched from VB.Net to C#. Talented developers didn't want to work on VB.Net.
-
-
Configuration.... in prolog....
-
Configuration.... in prolog....
Looking on the bright side, if someone manages to write a config file, they can prove it to be correct.
-
proof by contractiction:
Config file is written in prolog.
prolog is not a correct language for configuration files
therefore the configuration file cannot be correct.
Q.E.D.
-
How about Lua?
https://wiki.asterisk.org/wiki/display/AST/Lua+Dialplan+Configuration
Maybe I should have picked that... but you know, I was like "Hey, there might be compatibility problems, don't know if it will be supported, let's go with something native, surely that will be reliable!"
Yeah...
-
https://github.com/osmandapp/OsmAnd-resources/blob/master/voice/be/ttsconfig.p
Looks like in some places, you could make a reasonable guess about what you need to write/edit:
string('1st.ogg', 'першы '). string('2nd.ogg', 'другі '). string('3rd.ogg', 'трэці '). string('4th.ogg', 'чацвёрты '). string('5th.ogg', 'пяты '). string('6th.ogg', 'шосты '). string('7th.ogg', 'сёмы '). string('8th.ogg', 'восьмы '). string('9th.ogg', 'дзявяты '). string('10th.ogg', 'дзясяты ').
...that's not any more obscure than any other config language. But then, oh...
hours(S, []) :- S < 60. hours(S, [Ogg, Hs]) :- H is S div 60, plural_hs(H, Hs), pnumberf(H, Ogg). time(Sec) -- ['less_a_minute.ogg'] :- Sec < 30. time(Sec) -- [H, Ogg, Mn] :- tts, S is round(Sec/60.0), hours(S, H), St is S mod 60, plural_mn(St, Mn), pnumberf(St, Ogg). time(Sec) -- [Ogg, Mn] :- not(tts), Sec < 300, St is Sec/60, plural_mn(St, Mn), pnumber(St, Ogg). time(Sec) -- [H, Ogg, Mn] :- not(tts), S is round(Sec/300.0)*5, hours(S, H), St is S mod 60, plural_mn(St, Mn), pnumberf(St, Ogg).
So the language has to be able to describe arithmetic expressions... Javascript? Python?
-
OSMAnd
Looks like you're not the one who complained about this: OsmAnd-java
Not sure what it's but maybe it's a port.
-
OSMAnd is written in Java, because Android. They have a (probably heavily stripped down) Prolog implementation in their guts (a Java file or two) that parses these configs and executes queries against them.
However, nowhere do they say about the preferred toolchain to develop these, and what queries are given, and what kind of results they expect in return. I have seen Turbo Prolog in headers, for heavens' sake. Also, in the repository they have a ttsconfig.p which you are supposed to put in, and config.p which is somehow generated from it (I've never found out how).
Also, as of later times, they stress heavily on using text-to-speech engines (somewhat justified, as you can't have all names of all streets and villages and towns and cities read aloud in your phone), but this workflow leaves out languages for which there is no TTS engine ever.
(And I'd better not get started on how WTF-worthy is Festival documentation on how to teach it a new language. Start with assuming this is a new language, then somehow forget about it and go full steam on new English voices and how you use existing speech-to-text tools and existing AT&T data to do auto-labeling, without really telling much how this labeling should work at all and what the manual process looks like.)
-
Everything's a configuration file if you're brave enough!
-
fun fact @SockBot almost had a configuration file that was live javascript and was also self modifying.
that idea lasted about an hour and then the tequila wore off
-
fun fact @SockBot almost had a configuration file that was live javascript and was also self modifying.
If it isn't bad enough it's written in CPS…
-
Ugh, why not just use a configuration language (yes those exist) like YAML?
-
that's what i went with in the end. ;-)
-
That's why I switched from VB.Net to C#. Talented developers didn't want to work on VB.Net.
That's mainly because they're crybabies afraid other developers will make fun of them. VB.Net is basically C# with different keywords.
-
That's mainly because they're crybabies afraid other developers will make fun of them. VB.Net is basically C# with different keywords.
I got sick of saying this to people. Plus, they usually don't want to work for you after you call them crybabies.
-
That's mainly because they're crybabies afraid other developers will make fun of them. VB.Net is basically C# with different keywords.
A lot of VB hate nowadays is the stigma from the days of VB6 and earlier, and VBA. And if VB.Net still hasOption Base 1
andOn Error Resume Next
, then it's a stigma that's well-justified.
-
A lot of VB hate nowadays is the stigma from the days of VB6 and earlier, and VBA
Of course. But it's been unjustified for how long has VB.Net been around?
And if VB.Net still has Option Base 1 and On Error Resume Next, then it's a stigma that's well-justified.
Apparently it's never had those, at least as far as I can tell from a very short Bing.
Option base 1 doesn't bother me that much, in principle. If you're always coding in VB, and your base is always 1, what's the problem? IIRC a lot of earlier Basics started arrays off at 1.
-
OF ALL THE BLOGS REPRINTING THAT BLOG ENTRY why would you pick Slashdot?
-
Option Base 1
No.
On Error Resume Next
Yes, but as soon as you add exception handling to a method, the compiler insists that you remove all VB6-style error handling.
-
OF ALL THE BLOGS REPRINTING THAT BLOG ENTRY why would you pick Slashdot?
Because it drives some people crazy.
-
I guess I can't argue with that logic.
-
Option base 1 doesn't bother me that much, in principle. If you're always coding in VB, and your base is always 1, what's the problem?
There isn't one. But when you inevitably happen across a codebase where it'sOption Base 0
, and you don't notice…
@blakeyrat said:OF ALL THE BLOGS REPRINTING THAT BLOG ENTRY why would you pick Slashdot?
Because it's not a blog, it's a news aggregator
Although some writers do use it almost as a blog…
@Jaime said:@RaceProUK said:
On Error Resume Next
Yes
-
@Jaime said:
@RaceProUK said:
On Error Resume Next
Yes
Yea, but C# has a crappy convention for raising events. Every language has bad parts. At leastOn Error
and friend are only there for backwards compatibility.
-
Option Base {0 | 1}
was removed in Visual Basic .NET 2002 (the first .NET version), and stripped during upgrades. Almost zero programs were affected by gaining a bonus array slot.On Error {GoTo line | Resume Next}
is still around, and every bit as terrible as it once was, but there are compiler flags to make it a syntax error, and the documentation is littered with recommendations strongly urgingTry / Catch / Finally / End Try
and the rest of the Structured Exception Handling machinery. I know of no VB.NET app that usesOn Error
, and I've seen some terrible ones in my time -- not all of them my own.Bonus: VB alone among first-class CLR languages supports exception filters. You can use
Catch ex As Exception When IFeelLikeIt(ex)
, haveIFeelLikeIt()
do further evaluation on the exception or program state, and then decide to let theCatch
handle it, or not!
-
Yea, but C# has a crappy convention for raising events. Every language has bad parts. At least
On Error
and friend are only there for backwards compatibility.
You mean
public event EventHandler SomeEvent;
and
SomeEvent(args);
Seems perfectly sane to me.
-
-
RaiseEvent FrobnicateComplete(frob)
versus
FrobnicateCompleteEventHandler fceh = FrobnicateComplete; if(fceh != null) { fceh(frob); }
if (SomeEvent != null) SomeEvent(args);
Nope. Race condition between the null check and the actual raise. Bit me in a few WPF apps.
-
```
if (SomeEvent != null) SomeEvent(args);I was shortcutting :stuck_out_tongue: Anyway, you have a race condition; should be:
var h = SomeEvent;
if (h != null) h(args);Obviously only necessary in multi-threaded code, but a good habit nonetheless. @TwelveBaud <a href="/t/via-quote/47404/29">said</a>:<blockquote>`RaiseEvent FrobnicateComplete(frob)`</blockquote> Syntactic sugar; easy enough to add to C# :stuck_out_tongue:
-
Syntactic sugar; easy enough to add to C#
The fact that it's not there is the "crappy" part. VB already has it. There's no reason to make every programmer make a solution to such a common issue.
Also, due to VB being line-oriented, Intellisense is much better at picking up stuff you are in the process of writing.
-
better solution:
public event EventHandler SomeEvent = (a,o) => {};
trying to pull the lambda expression out of my back side but IIRC that works. you always have an event handler
of course you should include the null check by habit, because you might not be dealing with an event you created, but that way your library is safe from NPE when an idiot (probably you) forgets the null check
-
trying to pull the lambda expression out of my back side but IIRC that works. you always have an event handler
It's spot on ;)
ForEventHandler
anyway; others will obviously have to have different arg lists, and maybe return values too.
-
well for return values swap
{}
fornull
for argument lists... well yeah, but the compile will let you know how many there need to be.
-
you always have an event handler
Your consumers can remove any event handler, including the no-op one you added. The only safe option is to null check it at use time, which makes assigning a no-op handler redundant. Even if it works, it's still a crappy convention. VB gets it right.
-
Your consumers can remove any event handler,
true, it's extremely bad form to remove a handler that you didn't add.
The only safe option is to null check it at use time
i did say you needed the null check, right?
which makes assigning a no-op handler redundant.
redundant, yes. but relatively inexpensive and it can prevent crashes.
another way of doing it would be to do
(EventThingie ?? (a,o) => {})(eventArgs);
but that's not any prettier... although you could pull that lambda out into a class variable and call it this way:
(EventThingie ?? DefaultEventThingie)(eventArgs);
-
another way of doing it would be to do
(EventThingie ?? (a,o) => {})(eventArgs);
but that's not any prettier... although you could pull that lambda out into a class variable and call it this way:
(EventThingie ?? DefaultEventThingie)(eventArgs); ```</blockquote> …quills…twitching…
-
it's not pretty, but it works and it sidesteps the race condition.
;-)
-
There isn't one. But when you inevitably happen across a codebase where it's Option Base 0, and you don't notice…
Ah. So Option base 0 is TRWTF.
-
I've always done (pseudocode so maybe not quite valid C#):
public event MyEvent; protected void RaiseMyEvent() { if (MyEvent != null) MyEvent(); }
Kinda silly to argue about the null check when you can put it in a single function and forget about it.
-
true, it's extremely bad form to remove a handler that you didn't add.
"You" are the event source. We're talking about the behavior of the event consumer. There is no choice but to code defensively. Once you've coded defensively at the point the event is raised, the defensive code written at the point the event is declared is redundant. The fact that C# treats an event as just another delegate variable instead of having a first-class language feature for events in the problem. All those who are trying to show how it should be coded are answering the wrong question. The question isn't "How do I raise an event?", it's "Is C#'s event raising convention good?".
-
well you still have a race condition there.
public event MyEvent; protected void RaiseMyEvent() { var e = MyEvent; if (e != null) e(); }
there fixed it.
-
I don't think I've ever encountered a race condition with custom events on .NET. Most event handlers are wired up at application start (or form instantiation) and then never modified afterwards.
-
Wait, come back! You dropped something:
;
! ;)
-
"You" are the event source.
actually in that swentance i meant "you" to be the consumer.,...
There is no choice but to code defensively.
true, very true
Once you've coded defensively at the point the event is raised, the defensive code written at the point the event is declared is redundant.
redundant, yes, but not useless. You, the event declarer are not always the one triggering the events.
I'm not going to say that using events as a communication method is a good design pattern or not, but it is one i've seen used before.
-
Most event handlers are wired up at application start (or form instantiation) and then never modified afterwards.
granted: but that doesn't mean they can't be.
-
Wait, come back! You dropped something: ;!
wat? no i didn't you must be imagining things
-
Like the Orange Pencil Of Editing?
-
hmm? i see no pencil.
-
Sounded like a name of an artifact from a roguelike game... The Orange Pencil of Editing.