Even better: do memory management like taxes - there is a GC that knows exactly about things to delete, but you still need to manually predict what it would do - and the program crashes some time later if you forgot.
This is the most chaotic Idea that I want to see in a programing language. This might also help make programmers understand that memory can be a limited resource too 😆
I once used FORTRAN on a Harris computer. It was possible to declare identifiers with numeric names. So you could have an integer variable called 3, and assign it the value 7. From then on, 3 + 4 would equal 11. So easy to sabotage somebody's code by slipping in a declaration like that.
In many cultures the digits '4' and '13' are considered unlucky, so to avoid offence, the compiler will generate an error whenever it comes across these characters. Programmers will be expected to code expressions to avoid these values. Eg, "5-1" and "15-2" would not cause an error. Note that representing 13 by 14-1 would also cause an error since it contains the digit '4'. And there would be no builtin constant for Pi, so programmers would have to come up with their own ways of writing 3.1415 without using the digit 4. Variables that contain the character '4' or '13' would also generate errors. And to make the language kid-safe, it would also generate an error for '69'.
@@jan-lukas Yes, sorry I missed that. Perhaps the full list of offensive numbers needs to be configurable. I recall now that someone told me that in Vietnam the number 1 is generally considered offensive, such as in "He's our first born child, our number one child." So perhaps Pi could be written as 3.36359-0.222 (without a 1 or 4 or 13.)
I think you got a good idea there, but I'm also thinking PI should actually be in the language. But preferrably as 6.2830... like was suggested back in time when they were thinking about pi. Or just make it 3.0 like some people suggested to make it easier. Because that's a smart thing to do.
Hello, I 'd like to say I've fallen in love with BS, and am working on an interpreter for it. Unfortunately, I couldn't get static analysis to work reliably for DELETE, so I added a garbage collector. Now don't get confused, it's not a collector of garbage, but a collector that IS garbage. It works by clearing all memory every 13 lines unless specifically asked not to do so by writing the line "NOT YET", the space is part of the keyword. Now I do want programs written with my tools to be compatible with yours, so you still need to DELETE all variables, however my interpreter will only be able to warn you about 5% of missing DELETEs, by crashing at runtime.
Brilliant! Where is the language standard's or compiler's repository/wiki? I would like to fill in some feature requests :) ... like partial pseudo randomization of operator precedence... at run time
It's not really a programming language, but when maple gives you an error, rather than give information you can use to correct the error it gives you a hyperlink to the relevant help page on their website, many of which simply read "a help page for this error does not yet exist."
That's the same strategy Microsoft uses for the help sections in Windows Settings. It's annoying (not least because it always opens a Bing search in Edge, not just a hyperlink to the page in your default browser) but not a huge problem all the way up til the time the problem you're trying to solve has to do with internet connectivity. Ask me how I know.
Something I admire about ancient COBOL is the ALTER statement (ALTER labelname1 PROCEED TO labelname2). This has the effect that if you have a "GOTO labelname1" somewhere in your code, it will jump to labelname2 instead (after the ALTER statement has been executed; before that it'll jump to labelname1). Maintaining code with more than one ALTER statement is a horror, which makes it a perfect candidate for BS.
I like the alter but another COBOL example is PERFORM x THU y..... Some unsuspecting soul puts some code in between those parras... get's well... a present. You can add the optional "x TIMES" on the end for a good and proper job.
I wrote hundreds of COBOL programs for several companies; GOTO (except error-exit) was strictly forbidden throughout. You can do structured programming in COBOL!
They should definitely take a pillar of programming from the world's fastest embedded language, Lua: Variables are part of the GLOBAL scope unless specified with the "local" keyword. So if you typo a keyword, it won't error, it will instead create a global variable by that name. This will "reduce" compiler errors and maximize fault on the programmer themselves!
E.g. function Check(€val isMaybeA Number) 42 CRASH_AND_BURN unless €value !!=! 5 Delete €vall Creates global variable €value Doesn't throw exception even if €val is 5 Creates, then deletes global variable €vall If so, I like it 😁
What brain dead designer thought it would be better to introduce a runtime bug than to catch the error at compile time? In what fantasy world would introducing a random global variable be preferred, just so the darn thing would compile (but not work)?
@@gdmathguyDoes typescript alert you when you are making a memory safety error not documented clearly, that doesn't even give you an error massage at runtime, it just doesn't run it‽‽‽ Or can it fix self contradictory documentation?
PowerShell has a "Verb-Noun" naming convention for function names, where the noun should be strictly singular, and the verb should be selected from a list of approved verbs. If your code doesn't comply with this, you'll get a warning from the linter (at my previous workplace it was enforced in the validation process). BS should adopt this with a twist: The compiler should fail, whenever it finds an uncomplying function name, and the list of approved verbs should be undocumented, and left for the programmer to figure out.
To be fair, I genuinely love the Verb-Noun format for PowerShell functions. It's not strictly required, is more commonly "Verb - compound noun/specific descriptor", and you can find the approved verbs with the command "Get-Verb". After using it for years, I always use the same format without the hyphen in all languages as it makes the method self-descriptive.
I noticed that the string interPOLation used the dollar ($) symbol and not the Euro (€). I think using the symbol for the Polish Złoty (zł) would be more appropriate.
@jernejj5 I think it should be dependent on your region, but always giving you the most annoying one, like for EU use ¥, for US use zł and so on. Obviously has to fail if you run it in another region.
@@artemis_fowl44hd92 Code region locking, DVD style. Of course, for customer convenience, trans-regional transcribing should be offered as a service. €100 per variable mention, including the ones in comments and "Delete" statements.
ideas from MS-office: some instructions should be localized. i.e. goto, gehezu, allerà ... depending on the OS's language. This should also fail for executables, if you run an english EXE in france, it should fail with "goto command unknown, did you mean allerà?". Also depending on locale, the meaning of "," and "." should be swapped, not only in numbers, but also everywhere else in the language.
How about "AN ERROR HAS OCCURRED" ? The error could be one of: (a) there is a bug in the program; or: (b) the run-time code has erroneously decided that there is an error. HOWEVER, and independently of the above, there is also the possibility that: (c) a genuine error has occurred, but the system has failed to report the error. Naturally, you have to use your psychic powers to discover that this error exists, where it is and what it is.
@@gellertli2916 you'd still need some service which holds a masterlist of source content indexable by hash, otherwise you'd need to run a bank of GPUs to hell and back to figure out what to display- oh my god that should be a design feature.
@@vanesslifeygo Hm, not better but different. You can store the unique characters in the blockchain so noone else could modify them later on. And since the ladder is decentralized there would be no single owner of the whole "database" either.
I like the idea of identifying each LLC with its UTF-256 character. So, to transfer a sum of money or an NFT from one LLC to another, one UTF-256 to identify FROM, TO, SUBJECT, CURRENCY or object type, and quantity. And no error checking, If a bit error means I now own the GDP of China or Elon, oh well. And all timestamps indicate the transaction occurred in the distant past, so any possible statute of limitations has expired. Wait. Should I patent this?
The "feature" I hate most in Excel (as far as the code in excel is programming) is that function names localize to the computer language. So if your computer happens to be set to dutch, or german, or norwegian, or whatever you can't following English language tutorials. Microsoft even created a function translator you can download in the latest versions of Excel to fix that. If you choose to make BS interpreted, localize the functions to the language of the computer running it, so you need to offer a version of your script for every language computer.
Not just the function names, but also localise the variables. You have to use dot as a decimal separator on English computer but comma if your computer is set to Czech or German. Even better if declaration of strings had to follow local quotation marks rules...
@@arnes12345 VBA was localized in Excel until 5.0 -- which made it hell/unusable. Imagine "sub test()" would be "subrutine test()". "Option Explicit" would be "Alternativ Mådeklarerevariable" WTF!! Still I'm struggling to help my coworkers that have Norwegian Excel as formulas are Norwegian! So formula =VLOOKUP(lookupvalue; range; index) must be =SLÅOPP.RAD(lookup etc etc) I want to slap the programmers with a soft pool-noodle :D Could they just not make it multilingual???
Another suggestion from Lua: all variables are global by default, you have to remember to put the “local” keyword every single time if you don’t want weird bugs and memory leaks.
@@anon_y_mousse Sounds reasonable. It would be great to have some syntactic sugar to spare the poor programmers from typing though (errors can happen during typing), so I'd like to see some syntactic sugar like "glocal" for "local global" and "lobal" for "global local". The portmanteau type specifiers follow Reverse Polish Notation, which might confuse a new comer, but fuck them.
But make them truly global, like a a centralized server keeping track of the global variable and its current value, we might run into problems in the future when we colonize other planets though
My first programming language I learned as a kid was Pascal. For a long time I couldn't use "else" because the compiler would always return an error whenever I used it and I couldn't figure out what was wrong. At first I was thinking, maybe I have a weird old version of the compiler that doesn't know the word "else", but then I found someone else's programs that I somehow got on the same floppy with Turbo Pascal, peeked into them, and they were using else and it was all right. But I kept getting the same error, so instead of using else I had to close the if section and open another one with the negated clause. Only after a good while I realised that THOU SHALL NOT PUT A SEMICOLON AFTER THE COMMAND THAT PRECEDES ELSE.
@@martinjoster3282God WHY? On the bright side you could make your own Inno Setup installers with PASCAL script! when life gives you outdated lemons...
@@worldseriesofghosts3408 Probably a leftover from earlier days, but the idea of the course is to teach general programming logic and structure to be applied to other languages, and honestly Pascal doesn't seem like a terrible choice for it; it's got the base structures, and something like Python has a lot of conveniences and simplifications which one won't always find in their programming journey
I'm scared to think of what horrors the (clearly battlescarred) audience would have come up with, given more time. Every suggestion gave the reaction of "That's so evil, I love it". The best I could come up with is requiring any valid source code to be hashed and minted as an NFT by BSCorp in order to compile successfully / without a You-wouldn't-download-a-car--esque warning
I spent the whole part about useless variable prefixes waiting for him to announce that the prefix actually does something, like in Ruby. Maybe something like "€ prefix means it is heap allocated, ß as prefix makes it a stack variable." Of course, assigning a stack-allocated var to a heap-allocated one (or vise versa) doesn't work, you'd need some kind of special syntax to convert between them. Would make refactoring fun. Edit: Oh, I've got it! Converting between head and stack allocated variables can be done by calling a function (or a parens-less keyword) called convert with the variable to be converted as an argument. Of course, error handling is important, so calling this function/using this keyword would inject your current namespace with a head-allocated variable called "okay" (or something like that) which YOU are responsible for. So, everytime you call convert and forget to Delete okay;, you are leaking memory. And of course, okay contains a string, not a bool or something sensible like that!
I suggest that we use both of Japanese's quotation mark sets instead of parentheses, so that nested parentheses need to be given different characters like they do in that language.\ Lets us add 4 additional characters to our expensive keyboard while we're at it. I like it cause it would almost be useful if it weren't so annoying, and because it fucks up character spacing. i.e.: 「unless 『€i !!=! -1』」; Edit: more than two-layered nested parentheses should alternate: 「unless 『「€i * 2」 !!=! -1』」;
thing is with a language like this you have to be careful not to dip too far into esolang territory, instead taking inspiration from bad design in non-esolangs. What you suggested is something I'd expect more from malbolge than the language described in the video.
I'm just thinking: use the scoping rules of python and javascript combined. "this" will just go out of scope at random. Reading from the previous scope is permitted, and will bring the variable into the scope, but writing to a variable from the previous scope is not permitted, unless you ask permission first. Variables with the same name will hide access to the previous one. Oh, and loops will not introduce a new scope, but functions will. So for BS, let's say that goto-statements create a new scope, but line numbers do not by themselves.
@@tokeivo I like those ideas except 'this' going out of scope randomly, as it doesn't feel very fair or programmy for it to be random. Instead perhaps something similar to INTERCAL's 'PLEASE' where the rules for when it does and doesn't go out of scope are rigid, just not documented anywhere (like every 21st 'this' in the source code is in the global scope)
From BASIC, the language should require line numbers to be part of the source code. It has the advantage that you can move lines around without changing the execution flow of the program. That way, lines can be sorted in a way that are the most aesthetically pleasing.
I get the sense that line numbers are a holdover from when terminals could only display a single line. So... you should only be able to use ed to modify BS programs.
@@b213videoz First, modern BASIC doesn't require line numbers. And second, the line number is not comparable to the it's instructions address, so it's not comparable to machine code. I mean, unless you were considering line numbers to be labels... which is what they were in the dark ages of BASIC.
The use of UNLESS is genius. Rudolf Flesch who wrote "The Art of Plain Talk" remarked that sentences which contain "unless" are among the most difficult to understand.
To be fair to Ruby, "unless" (and being able to put it at the end of a line) isn't actually original to Ruby -- it originates in Perl, which Ruby actually takes a lot of inspiration from
You forgot one of the best ones. VB6 (and VBA) use Bankers rounding. So 5 is rounded up or down depending if the next most significant digit is odd or even. But that would be far to easy ... BS should round up or down depending on if the line count is odd or even.
Sounds too simple, the Douglas Adams principle should apply here as well. If the round function has been used for the 42nd time, then we round the number the other way than expected as we see for the other 41 timeas.
MATLAB is a treasure trove for this. - forgetting a semicolon at the end of the line will echo anything - Round brackets are used both for function callings as well as array indexing - You can use [] or {} for array indexing as well, however, their behaviour and rules depend on the type of array you are accessing, and they are NOT interchangeable. - 'a' is a character array, but "a" is a string. Completely different things. - The + operator on character arrays will treat them as vectors, performing element-wise addition of the ASCII values of the characters and returning a new character array. If the char arrays have different lengths, it will crash. - On the other hand, the + operator on strings will concatenate them. What happens when you + a string with a char array? I can't remember, and that's an issue. - Built-in functions have inconsistent behaviour with regards to strings vs char arrays. Most (but not all) will will accept either as arguments. Some (but not all) will return the same type you gave as input. Many (but not all) will convert strings to char arrays and return char arrays. How can you tell how a built-in will behave? Not from the documentation, because that would be too easy. Fire up your matlab instance, re-activate your license for the 15th time, wait for the IDE to spool up, and try it out! - And so, so much more...
I'm a mechanical engineer who knows just enough about programming to know that this is hilarious and would be infuriating to use. It reminds me of a time in school a couple years back when I was talking in some of my classmates about "Anti-CAD," similar concept for 3d design. Points had to be circles with zero radius, threads had to be made with a virtual tap or die tool (which had to be turned the right number of threads with the mouse)... I forget a lot of the really funny/annoying features but it was a good comedic break from serious study.
All 3D cad objects must use completely parametised 2D sketches before it can extrude. Then make parameterisation break with anything outside the smallest adjustments. Or Autocad light where parameterisations are behind a paywall. Or do what SpaceClaim does and make all basically all 2D and 3D operations pushing and pulling the sketch with the mouse.
33:56 In Norwegian, there are three gendered indefinite noun articles (in addition to plurals), and so the compiler can also throw a cryptic grammar-checking error if the noun doesn't agree with its gender.
Of course you then need to know the gender for any custom type, so programmers will have to specify the gender of their classes unless the class name ends with a word from a dictionary built into the compiler, in which case specifying a gender is obviously invalid.
If you're going to do that, then why not force conjugation of the various commands so they agree with their subject (singular, multiple object operations), tense (imperative, timeframe), and mood (likely branch, unlikely).
And at the start of any program, you must put in a declare block, outlining the declared pronouns for every class & function in every scope. Any he/him function is sent to die, every she/her is considered hysterical and ignored, and any they/them is considered plural, requiring the use of areProbablyA. And if you don’t include at least one gender with an x in it, the program throws a bigot error and refuses to compile.
What you can also do for comparison is that when comparing with undefined, the result is not true nor false, but undefined. When checking for equality with null, the result is not true nor false, but null. And if you check that undefined is equals to null, the behaviour is undefined and produces random result each time. Inspired by SQL.
Guys! There is an obvious oversight! Just like in JavaScript, “this” should not always be “this class”. It should sometimes be some random object in memory, depending on what time the code was run at! Amazing debugging sessions!
I like the idea that "this" in a class will act upon the class itself instead of on the instance, unless in the __construct method you call some function built into classes implicitly that isn't documented anywhere. Something like `this.createInstance()`. If the __construct is called via `super()` then it will skip over `this.createInstance()` meaning EVERY constructor must call it and it must be called before any super calls, which will directly conflict with "no this access before super", meaning inheritance is implemented but utterly impossible at compile time.
was so struck by this gem the last time I watched him give this talk that I called it Rendle's Law: "There's nothing you can suggest that is so unutterably stupid that people won't waste their time attempting it"
My Idea: every type should have it's own "null" type. For example: "NotString" for string, "NoNumber" for int, "MissingFloat" for floats etc. The less consistent the naming, the better. And of couse, no easy way to convert between them.
Awesome. I think the Delete should have a safety feature borrowed from operating systems. Delete doesn't delete anything, it puts it in the Trash (or recycyle bin if you're on Windows). So, Delete all you want, that space in memory is still in use. You need a second step to reclaim it.
You could actually use this to return values from functions, the caller uses UNDELETE to retrieve the last value(s) that the function Deleted. That would mean the caller had to know the order of Deletion, making the code extra brittle.
@@MarkRendle RUNDELETE to do a Reverse UNDELETE in case you wanted the first item ever Deleted (but since the trash has no scope, it could be anything that was deleted)
"COBOL was made so business people can write their own applications the way they want. But they can't even describe the business programs they want, much less write them" *Java slowly edging towards the door*
COBOL was written so that it could be compiled on very small machines for the time, and of course also on the larger ones. Thus, a source program was divided into four DIVISIONS to establish, before seeing the procedure code, the more global metadata about the program. The IDENTIFICATION DIVISION gave the name of the program, who owned it, when it was written, how to handle security, and any other administrative information, including a tutorial on how it works. The ENVIRONMENT DIVISION told what special options the computer must have, and how to allocate input files to actual hardware. The DATA DIVISION described the layout of each file and its data records, and the name and layout of each working memory data variable (and in later versions, the names and layouts of parameter records passed from the calling program). And the PROCEDURE DIVISION contained the actual processing logic statements. The compiler could therefore be built in overlay phases for small machines: the first phase only had to be able to parse the IDENTIFICATION statements; the second phase, only the ENVIRONMENTAL statements; etc. COBOL restricts program variables from duplicating the spelling of reserved words so that, in putting out the temporary source code, each token could be converted, in smaller machines, into a compressed form, such as an index into the symbol table being accumulated; reserved words would be an index into the reserved word table, etc. to make compiling on really small machines possible. And also, it was intended to allow managers to be able to read source code and learn how each program fits into the customer’s library, with minimal or no explanation from any programmer (thus, it could be written to be “self documented”). FORTRAN originally had no syntax for saving the result of a comparison (the IF statement tested a single number (or expression), and designated a specific statement number to go to if it was negative, zero, or positive). FORTRAN IV introduced Boolean values, of which the value of a bit was represented in the program as “.TRUE.” or “.FALSE.” The comparison operators were “.LT,” “.LE.,” etc. and the combining Boolean operators were “.AND.,” “.OR.,” and “.NOT.” This was because the character set was very small. FORTRAN also used statement numbers instead of labels, but not every statement needed a number, and they did not need to be consecutive.
@@cadaankaa For some folks it is. But it also allows ADD 1 TO COUNT, which is shorter and easier to understand than COUNT = COUNT + 1. And it also includes long names, so you can, for example, write MULTIPLY TIMECARD-HOURS-WORKED BY EMPLOYEE-HOURLY-RATE GIVING OUTPUT-GROSS-PAY. This was good for reading and understanding programs written by other people.
In some math classes I would see the teacher alternate between () and [] when nesting parens. Why not do that in this language? Something like a = (b + 3 * [6 / (2 - c) ] ) / 7; If the parens don't alternate correctly, "syntax error. press any key to continue." and the compiler waits for the response before exiting, making automation of compilation just a little bit harder. If someone wants to add something in the middle, they have to change the inner and/or outer parens to alternate correctly. let's make the outermost level have to be (). That way if they want to add another level on the outside, they have to change everything inside. also, let's make / and * evaluate from right to left, so to get the natural interpretation they have to use parens. evaluate all * before all / so it's even more confusing. Cite PEMDAS if anyone gripes. use e as a keyword for exponentiation, but not like everyone else uses e. 1e7 should evaluate to "1 to the 7th power" instead of "10000000".
Nice, but in a future revision we should consider matching different types of parens thus: (b + 3 * [6 / (2 - c] ) ] I would also like to see + and - have higher precedence than * and /, and - have higher precedence than +, unless we're calculating array indices in which case it's reverse. I also think the semicolon could be overloaded as an arithmetic operator when next to a number literal, casting the number into a semi-float. It could potentially make the language so expressive.
Index Origin: Most languages start counting from either Zero or One. BS sets the index origin to simply -1. APL allows one to dynamically set and modify the index origin to either 0 or 1. So separate threads may have different values, or the value may vary within a loop, or different functions. However, if the index origin is undefined in the code, APL uses either 0 or 1 dependant on the users predefined preference, so the value will depend on who is running the code rather than who wrote it.
Conscientious programmers set ⎕IO to the required convention in local function scope. This barely dents the gyrations one performs as a conscientious shell programmer.
Allow me to suggest a better way of implementing multithreading: The GOTO statement accepts multiple line numbers. When you give multiple numbers, the process forks with each child process starting from one of the line numbers given For example, GOTO 42 84 spawns two processes - one starting from line 42 and the other from line 84
lets do a step beyond! instead of goto, lets have a COMEFROM multi threading just like intercal you can put a COMEFROM anywhere in your program, and when it reaches that line. it starts execution from the COMEFROM in a new thread... without any warning in the code that is actually running at the time
@@JordanManfrey And all functions should be async by default for performance like in Express, so you need to wrap and await everything to make it synchronous.
I suggest that your DDE (disintegrated development environment) should treat tabs as four spaces but display them as three. While I understand the idea behind an odd number of spaces being a comment, I also like the REM function, which made BASIC have to evaluate comments while running. It does so much to improve (lack of) efficiency.
A few ideas: - have error message line numbers also made -1-based (and column position starting at the end of the line) - you have classes, so make the inheritance dynamic and easily overridable to any other class in the program. So you can easily access a field in a random class even if it's private, by quickly changing the base class to that, read it, and set it back to something else. - you did not play with #pragma... there should be one that rounds every number to an arbitrary low precision (eg. constant Real_Pi !=! 3.1 when the file has #pragma MediumPrecisionON somewhere on the top). Also, when using '#pragma SECURE' every identifier needs to have minimum 8 characters, an uppercase, a digit and a special symbol to be valid.
Yes, the language should definitely not allow immutable data types of any sort. The values of variables should spontaneously change if the programmer neglects to set them within a certain time.
1. Error messages should be based on number of characters before (or after) the line where error occurred. 2. R language will change the type of your variable on the fly, if it cannot process the inputs properly, say to a matrix.
Of course, BS is secure by default, so that's the default. You need #pragma INSECURE before declaring any identifier that doesn't meet those requirements.
First rule of programming: users don't like errors. In their endless wisdom, the developers of Visual Basic invented ON ERROR RESUME NEXT, which wraps literally every statement in an error handler that just silently swallows every possible exception. Even if the complete code is totally unusable due to some null reference error in the very first line, the user must not be bothered by annoying messages, especially with scary stack trace information. In BS actually this should be the default behavior. Though it makes it a bit harder to identify the root of the problem, the user will not freak out, maybe just notices that something is slightly off. Of course, there are some serious cases when crashing is the better option. So I suggest an UNLESS CRITICAL extension to the command, which may enable crashing in some circumstances. Judging the "criticalness" must be left to the executing runtime: even the same error might be considered differently, depending on some parameters such as the temperature of the CPU, for how long is the app running, etc. But even when crashing, no scary debug information must be displayed to the user.
5:40 COMEFROM is actually not semantically identical to GOTO if you allow to use multiple COMEFROMs for the same source. This way you could've introduce non-determinism or parallelism in some way, however you define the semantics.
yes. I kept finding myself wondering how old the speaker actually was, especially during the INTERCAL part. COMEFROM was one of the more subtle jokes in INTERCAL, and I think you needed to be involved in the language debates of the day to truly appreciate the commentary contained in it
COMEFROM should start a new thread every time it is used to reduce overhead. Though since there is no GOTO, every time you use COMEFROM and don't want a new thread you will need to end the program immediately after the line you are comming from and let it continue in the new thread.
Variables should leak out of scope like in python. By default, you will use the identically named variable from the outmost scope, but Local keyword can be used to use the innermost scope instead. Be careful not to Delete the outmost scope variable, since those scopes will start using the next outmost variable instead (which was probably the Local variable you wanted to Delete).
OMG this is the second least favorite Python feature of mine, after significant white space. We should definitely have it in BS, it would be brilliant!!
there seriously is a bs language - developed by someone at AT&T Bell Labs back in the 70s. Can kind of think of it as the Perl of the 70s. But seems to not gotten any traction and faded into obscurity. I have a 9 page manual for it: "Bs is a remote descendant of Basic and Snobol4 with a little C language thrown in. Bs is designed for programming tasks where program development time is as important as the resulting speed of execution. ..."
@@fllthdcrb SNOBOL4 was big on the IBM mainframes like the 360. It came out in mid 60s (in a portable version that ran on a virtualized machine - implemented with assembler macros). It was adept at string pattern matching so it may very well be the granddaddy of regular expression grep-like libraries and tools and clearly, per that blurb in the BS manual, the folks at AT&T Bell Labs were aware of SNOBOL4 so perhaps that is indeed what they drew on as inspiration for the the regular expression capabilities that they made famous in tooling, libraries, and languages (well, Perl was Unix inspired and had integral regular expression capability)
@@TheSulross SNOBOL4 was a useful language - once you got your head screwed around enough to deal with its syntax and got used to the 'space' as being a significant character. I think the Griswold, Poage, Polonsky SNOBOL4 manual was the worst I've ever encountered: useful only if you are already intimately familiar with the language. I spent a lot of time reading the Index line by line, looking for something suggestive of of what I thought I needed.
@@walterpinkus5534 I recently listened to a podcast on SNOBOL and it seems it was mainly a thing on mainframe computers back in the day. The Unix world developed it's own approach to reg-ex tools and capabilities (unclear if they drew on inspiration from SNOBOL - which had been around since the 60s) and that heritage for reg-ex text processing is what survived into the contemporary computing landscape
I saw his first talk like this, I think it is 7 years or so ago. Also just as funny - this is just the updated one 😃 Edit: i was close - ua-cam.com/video/hCvHTrUh4os/v-deo.html
You have to put in pointers as most people are really confused by them. But instead of being a variable pointing to the memory location of another variable, a pointer in BS stores the line number the variable is declared in. In order for this to work, the variables you want to point to have to have line numbers added during compile time, of course. In code, you then get the line number a variable is declared in using the FoundIn keyword. Dereferencing the pointer is very intuitive and works as follows: You create a string containing code to GOTO the line number with the variable declaration, then get the sourcecode of this line using GetCode and use RegEx to modify the line to not declare the variable but read it's value. This code is then executed using EVALUATE so you can also use pointers in a multi-threaded environment.
@@weakspirit_ In Hypertalk, the programming langauge invented in the late 1980s for use on a Macintosh program called Hypercard, there was no cleanly-identifiable distinction between strings and numbers, and the comparison operator was non-transitive. '5' > '14x' > '12' > '5'. Javascript can be about as bad when compring strings and number objects, but at least in Javascript a string comparison between "12" and "5" will report the latter as greater. In early Hypertalk, the only way to force string comparisons would be to prepend a constant to both strings that would prevent either from being interpreted as a number.
I vote for invisible implicit variables, like *$_* in Perl. When reading code code you have to remember every circumstance where they might appear (or rather, _not_ appear).
During runtime, your program should initialize a "registry". Every time you create an object the program should assign it a GUID and insert it into the registry, and return the GUID value. Anything that isn't a basic data type should be stored in and retrieved from the registry, including classes, structs, and arrays, and their GUID is stored in the program using the new GUID data type. This way you can limit those annoying custom types, because they get in the way. Names and internal data are still important, though, so you can store that all as subkeys. This is great because you aren't forced to follow the defined layout of a class like all the top languages force you to, and you can even do it without defining a new class extension!
Registry initializing should be done at compile time, run time would require the registry initialized. This way you can't move the compiled program to another machine unless you have the proper registry keys. Registry keys should not be grouped under a single root but rather scattered all over the place under the sha256 hash of the class (struct, array) name.
@@joseluu260 I like this a lot, but I fear we need some more security and we should also require keys to use our language. We can't have random people using our language for who knows what! This way we can also include the user information in the hashing and make it so your code only runs on your computer, even if you initialize the registry keys. You know, for security.
A Greek semicolon is actually just the top dot from : I think a better option would be to combine with Spanish and always pair punctuation with the opening mark being upside down 🤣
Even better: Make it MatLab (but in Spanish) (yes, that's it's actual name "MatLab (but in Spanish)") If you forget either the opening or closing punctuation (unless constructs require one at the very start and at the very end) the ENTIRE construct is evaluated and printed before the condition is evaluated and the branch taken is evaluated a second time (including all side effects) Open questions: What happens if there are early returns in either of the branches? What happens to Delete's in either branch? Bonus points: FOR EACH missing punctuation both branches are evaluated and printed... Missed the first? That's 1 evaluation for both + 1 for the branch actually taken Missed both? That's 2 (!) evaluations + 1 for the actual branch!
Absolutely. A real draw to get coders to conferences. A head liner….can you tell I am an ex programmer who slipped into marketing dev tools? Hey, I am always trying to convince business degree marketers WHY they can’t use “user friendly” in every single ad…to use info that has context.
Inform 7 is a "natural language programming language" designed for writing text adventure games. It was intended to be easy for people who are primarily writers and not programmers, and I quite like it despite being more of a programmer than a writer. Nevertheless, it has some very weird features: Identifiers may contain whitespace. It's ok to refer to a variable by just part of its name, but you do risk confusing the compiler and referring to some other variable that shares part of its name. To declare a variable, you give its name, its type (which is called a kind in Inform 7), and then you have to declare that it varies. If you don't declare that it varies, then you've just instantiated an object (which is called a thing in Inform 7) instead. A gadget is a kind of thing. [this is a type declaration specifying inheritance] The really keen blender is a gadget. [this creates an object] The nifty garlic press is a gadget. The rustic mortar and pestle is a gadget. [this may cause problems for the compiler because the name contains the word "and"... but maybe it won't, who knows?] Jenny's favorite appliance is a device that varies. [this may cause problems if there's also a thing called Jenny... but maybe it won't, who knows?] If you want to write a function called "it's raining" that returns a boolean, you say: To decide whether or not it's raining: "unless" is a keyword in Inform 7. If you want to write a function called "flush the toilet" that doesn't return a value, you say: To flush the toilet: If you want to write a function called "the favorite appliance of" that takes a person as an argument returns a gadget, you say: To decide which gadget is the favorite appliance of (the subject - a person): There's way more, but I can't even remember how it works right now...
I feel like I'm in a weird limbo between Stanley Parable and Stephen Fry when watching this content. Some of the most absurd concepts delivered with a dry English comment made me laugh harder than I ever thought I would at programming! Thank you for a great presentation!
Aw man, I was waiting for Perl's contexts. You know, when operators such as ASSIGNMENT mean different things depending on context, which is implicit and inferred. This is the best comment section I've seen in years!
I thought of something perfect to add. TCL has this feature called "upvar" that lets a function access the scope of the function that called it. It can take a number parameter to access higher levels of the call stack.
I think Lua metatables could be integrated by adding a massive amount of overhead to each memory access, and of course these should be mandatory for some obscure datatype, and extremely difficult for the programmer to implement correctly. Since it would be so special and would generate a much larger compiled file if it is used, why not show it's significance with, idk, BS_Set_META(€a,€b); and of course, since the function was broken in the first release, we need to include the fixed function as well with every release: Set_META_real(€a,€b); (!note: this one not prefixed with "BS" in order to comply with 69% requirement)
I recently learned Python and I like it quite a bit. It is actually very much like Lisp, the language I’ve used the most in the past. But the concept that spaces are part of the language is something I thought was brain-dead when I first learned the language and something I still think is brain-dead. Of course, with a decent IDE, it’s easy to keep track of, but a decent IDE also makes it completely superfluous because a decent IDE can autoformat your code anyway. I still prefer parentheses or some other characters to mark beginning and end of a code block. It’s completely unambiguous and requires less effort than typing five spaces.
I agree 100%. Some time ago I needed to update a Python code without any previous contact with the language (I had worked with things like Fortran and especially C/C++ for decades). The job was quite easy but I remember that I needed to call my son-in-law (a developer) and ask him: "Is it real? Do they actually use whitespace as part of the Python language?".
My first computer job was translating 1960's APL code from printouts and program outputs to applesoft Basic. I was 18 and had no idea about APL, but I BS'd my way into the job and they gave me a 5ft high stack of printouts and a APL textbook from the 1960's. That paid for my first 2 years of college.
I think you should add "template" before every function to make sure that compiler errors are completely undecipherable. Also, if you fail to put "template" before your function you should get a fatal warning from the compiler. Just that. "Fatal warning.". For every function definition. However, we are not that sadistic. You can of course turn of these irritating warnings with a compiler option. Which will implicitly put a "template" line before every function, and these extra lines are counted by the compiler so that all your compiler errors now refer to line numbers which are off by an extra line for every function in the file. And if you really want to win over the C++ crowd (in addition to the COBOL warriors), a BS program MUST be completely constexpr.
I think 'missing constant' would be a worse error message. Reason behind name: missing 'template' => missing nothing (no template types) => missing null => missing constant (since null is a constant)
Ok, but making the language strictly useless seems excessive. If everything is `constexpr`, you can't do IO... unless your notion of `constexpr` is borked, which could be a "good" feature.
The problem with forcing everything to be constexpr is that you would then know what's going on. You know that your output binary will always return a single value and close, so deciphering the code is about figuring out what the value is. constexpr generally makes code simpler, since it explicitly PREVENTS you from writing code with some clearly defined properties (being determinable at compile time). A bad language is one that lets you do lots of horrible things, but prevents you from doing seemingly normal things with no rhyme or reason.
Brilliant talk... No NUL moments! Just yesterday it took me around 30 minutes to figure out why one particular basic Latin character in my jpeg code registered as 2 bytes when I highlighted it. It should only have registered as 1 byte, Until figured out that the character was paired with a non-breaking space character (Alt0655), being of course completely invisible. There are definite time-saving advantages switching from ANSI to UTF-8 when working with image binary...so I gave meself a pat on the back😄
5 amazing suggestions from the audience sounds like some sort of record. Thank you for the excellent talk Mark! I was initially afraid this would just be a repeat of the old 2014 talk but no - it (being the BS language) is far worse and the talk is far better and more refined!
Actually... 2:22 - speaker gets real confused and doesn't reali as that that first two, and last several, lines in his example COBOL program are JCL (job control language) which was used server side like a .bat file, to load and start the actual COBOL program, which is, for some reason embedded in it here, instead of merely referenced by it. The rest used some things li me being able to create short names for stuff like the output location, i.e. console in this case, which was added on the theory that a CNSL was several bytes shorter and thus saved huge amounts of program space. Which I suppose 'might ' sometimes matter on really old systems, with super tight memory constraints... In any case, JCL was intended to load "any" process/program, not just stuff written in COBOL, hence my comparing it to a DOS .bat file.
Actually... 2:22 - speaker gets real confused and doesn't reali as that that first two, and last several, lines in his example COBOL program are JCL (job control language) which was used server side like a .bat file, to load and start the actual COBOL program, which is, for some reason embedded in it here, instead of merely referenced by it. The rest used some things li me being able to create short names for stuff like the output location, i.e. console in this case, which was added on the theory that a CNSL was several bytes shorter and thus saved huge amounts of program space. Which I suppose 'might ' sometimes matter on really old systems, with super tight memory constraints... In any case, JCL was intended to load "any" process/program, not just stuff written in COBOL, hence my comparing it to a DOS .bat file.
Here are a few ideas to add: Bash scripting uses a wide variety of character pairs to enclose conditions - parentheses, square brackets, double square brackets, etc., and what is or isn't allowed in the condition, how you write it, and, in some cases, whether you can even do the comparison changes depending on the enclosing characters. Thus, BS unless (null) would not do the same thing as unless[null] and unless [foo == bar] might be a syntax error while unless [[ foo == bar ]] or [ foo ∙eq∙ bar] might be legal. (FYI, I used a 'bullet' character around the eq, for much the same reason you used the Euro symbol.) You discussed adding a required "break" statement for each scope. If a break is omitted, what happens? I would propose that execution simply continue with the next statement, ignoring whatever condition might or might not have been (intended to be) applied to it. Thus, if you omit the break statements in an 'unless' conditional, the code would act as if the 'unless' statement was not there. If you were to include a switch or case statement, I would suggest again borrowing from bash - their case markers are a value followed by a single ')', which makes parenthesis matching for finding errors completely useless. You could also take the case terminating ';;' and expand it to 'break break'. At the end of a case: if there is no break statement, fall through to the next case's code, if there is only one break, continue with either the case after the next case, or the otherwise case, and if you have break break, leave the entire case statement. I think having a 'come from' could be interesting, but it should only be allowed inside loops or conditional blocks. It might possibly be allowed inside function bodies (outside of loops or conditional blocks within the functions), but only if the source location is outside the function body, which is to say that it provides a way to jump into the middle of a function. Of course, there is always the Cobol ALTER statement....
if test '$var1' -eq '' -a "$var2" == True ; then echo "$vElem=${vText[$vTeSu]:0:4}" ; fi # Welcome to bash, best language ever! Some languages put a number after the break, indicating the number of levels to break, so if you have a while inside of a while, break 2 would break out of both. You then get interesting effects when a new programmer takes over and inserts a for loop between the two while's! A "goto" could be used to prevent this "bug", but we all know that goto's are bad and lead to spaghetti code. I would use break 99 to be safe -- break 99 levels. An even higher number may be needed if the program goes into bottomless recursion.
[foo == bar] failing vs [ foo == bar ] working is a nice addition, but it should just be accepted with a different meaning.... like [foo == bar] is [ foo == bar ] but in global scope
Absolutely the most hilarous hour I have spent since I was first exposed to programming languages, some 48 years ago! Thank you for the overview of this fantastic programming tool, BS!
I have found a bug in the BS specification. It seems you, inadvertently, allow multiple "and"s for a single do, meaning you could do 4 parallel threads like this: do: thing and: thing and: thing and: thing Clearly the intended syntax is to simply nestle them, like this: do: do: thing and: thing and: do: thing and: thing Which we can all agree is probably what you meant :)
But they do different things! First starts 4 threads, second starts 2 threads that start 2 threads. Actually making the whole program fork at that moment would be even more diabolical.
It should have been implemented as unix fork(). The program flow after fork splits into 2 threads, fork() returns zero for one thread and non-zero for the other. So instead of do: thing and: thing onw would write: thing; else thing; unless fork() == 0;
Do not let the lovely British accent deceive you. This man is creating a monster right in front of you by combining every ugly conceivable feature you could possibly hate. He tells you he will concoct a terrifying, brilliantly horrible FrankenZombieLanguage, and he even gets the audience to help. I am suddenly applauding him for showing what kind of bastards live in this world, who will directly harm mine. He is the John Oliver of coding.
A programmer's hell involves sitting in front of a single console running BS where the only way out of your otherwise eternal torment is writing a perfect BS compiler using BS. You don't get access to any documentation, syntax highlighting or anything. You have to work in raw text files. As a side bonus, your chair is very uncomfortable and you don't get any coffee.
The #define with regex replacement is actually pretty ingenious. It lets you create a simple ad hoc DSL within a source file. I have use cases for that, I guess.
It's even more amusing that since you put a string after a hash symbol, the youTube analyzer is following the example of Twitter, FB, Instagram, etc and created a hashtag out of it. Clicking it in your comment opens a page of videos it thinks are related to "define". lol.
Yeah I said the same thing. This would be pretty great. Though I think to make it more spicy, it should apply to any subsequent #defines later on. So you can use macros to write your macros.
After 40 years of writing software I can attest that Academics and Mathematicians should never be allowed in the design of programming languages. Logo is a terrible implementation of a good intention. Current C++ is a nightmare complication of a great idea. NodeJS is under planning extended to insanity. Python is bureaucratic punishment of programmers.
This is such a fun talk! I could be wrong, but I believe you've introduced a memory leak in your Say function. You're not deleting the €things variable. 😉 C# also has the confusing "skip parentheses" on object initialization if you use curly braces and set some properties instead.
Great presentation, I couldn't stop laughing. I feel old that I know about all the items he used from the languages. Option Base was what you used to set the array index in VB6. I wrote tons of VB6 code. You also had to create a '.bas' file to set globals. I do not miss that language
You didn't need Option Explicit as you could dimension the lower bound, eg DIM f(0 To 10) or Dim (1 To 10). You could make it anything, eg Dim f(-100 To 100) or Dim WWII(1939 To 1945) so you didn't need a variable to hold an offset which you always got wrong. I wished they'd kept that.
I recently began programming an embedded system using Zephyr RTOS. Its been a while since I have setup a C build. I had to review the Make language, learn about CMake and Ninja, that build Make scripts, then learn about West to build Ninja scripts and KConfig for build configuration. On top of that, Zephyr has decided to borrow Device Tree from Linux to configure boards (because of course everyone knows about Device Tree), but to get the device tree configuration actually into the C code, drivers need YAML files as glue. The device tree files create macros that are nested many levels deep, so that whenever there is a problem, you get an error like: 'PINCTRL_STATE_DT_N_S_soc_S_pwm_40021000_PINCTRL_IDX_0_UPPER_TOKEN' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_pwm_4001c000_PINCTRL_IDX_0_UPPER_TOKEN'? So, for BS I propose a separate language called CRAP (Configuration Reader And Prognosticator) to do build configurations, Wipe to cleanup build artifacts so they don't get checked in to the repository, and Toilet as the name of the compiler. Of course, all CRAP options are declarable on the Toilet command line, but formats are completely different. And, we need a name for the "ecosystem". How about Septic?
Absolutely brilliant! Could I suggest adding from PL/1 (coming from Fortran if memory serves): implicit typing based on the first character of the variable name (which is why for loops traditionally use a lowercase "i" as it was the first short int available)
also Fortran's implicit save. If you assign a value to a variable on the same line that you declare it, the variable is given the save-attribute. This is basically the same as a static variable, so it will not be reinitialized on the next function call.
From TeX: There’s a special “expandafter” macro that causes the macro engine to temporarily skip the next token. If you want to skip more than one token, you have to use additional expandafters (since expandafter is a macro, you can apply it to itself).
One more beautiful code design suggestion adopted from Arduino: instead of a=b you put assignValue(a, b->value()), and moreover, the HelloWorld project should include a builtin initialized 4GB of memory for buffers and predefined one-letter variables.
I love this video. I have some suggestions: Using infix notation in BS is too much polite I think. The postfix notation is just for BS! So, the "unless €i < 1 break;" should be written as "unless €i 1 < break;" Also, using '' signs is too much readable, the bash "lt" and "gt" is more appropriate, so the "unless €i < 1 break;" will be written as "unless €i 1 lt break;"
Postfix notation (RPN) is too familiar to users of graphing calculators and happens to be the natural sentence order for several human languages, including Japanese, Latin, Turkish, some constructs in Romance languages, and so on. Make it prefix notation instead, after all, you have to know what operation to apply things to before knowing those things, right? + - 20 * 3 4 1 = 9
2 роки тому+36
Thank you Mark for these germs of inspiration. Despite a well structured and rich language we got ourselves already, here are a few improvement suggestions. - is for instanceof, and null is everything, and is a type as well (thank you typescript) whose only instance is null itself - Just like Java generics, add erasure at compile time - as feature, please - Just like the JDK, be backward compatible no matter how modern the world become - Just like Java compiler, compile nested classes as first citizen files - Java is so awful it could well just be SP. When litterals are passed as parameters, optional type, if specified, must be the wrapper type instead - Please, stop listening to the community. Just follow Microsoft lead, because you know better (starting with my suggestions here) - Make your package manager use a different language and stack, like groovy and gradle in Java, or cargo for Rust - The compiler to follow Rust and optimize everything recursively... And if there's ambiguity, interactively ask the developer to pick from some variants - Talking of PHP/Wordpress or Ruby/OnRails... Well, make a frameworks which design imperative determines which feature gets into BS - I already love this one. Programmed obsolescence of keywords. That !important to sustain the hype around BS and get people to forcefully upgrade to latest features - SQL got `DESCRIBE TABLE` but Postgres? Well, some keywords can start with backslash - That no-parens function call should not be for zero-arguments but 7-args functions call. Just that - From JavaScript, assigning a method to a variable disconnects the this context - pure evil - Like Redis, you can make BS scriptable (you did EVALUATE) but those scripts should be in LUA (a different programming language, or SP v.2.1.3 specifically, yes) - Make a special engine to run BS and then, make it paid by companies with +50 employees ^^ - If anyone ever make something successful despite all eveil in BS... Please sue them to get your share.
"Business people can't even describe the applications they want, much less write them." This made my day - this statement in the opening section alone made watching the whole 1h video worthwhile.
The problem is that many people took it as a blanket no. For certain types of code, such as error handling or nested loops, using goto can make your code cleaner and more efficient. Nearly all things in life should be done in moderation. /* There are exceptions, of course. Like always comment your code, but not every line. */
@@anon_y_mousse Ironically, COBOL has the more elegant and more structural "continue" (and "next sentence") statement replacing the more unstructured and more error prone "go to" statement within iterations. COBOL also has a more structural "evaluate" statement solving multiple elseifs with multiple complex condition statements. Unknow for those who never coded COBOL, it has been the stable and reliable backbone language of the financial world. It might still be, I don't know, I haven't programmed COBOL for over 20 years. p.s. I also used to be a Java programmer.
@@wimahlers Interesting, although C does have the continue keyword as well. It's just not enough in certain circumstances. Like if you want to break out of an inner loop and you haven't yet met the condition of the loop, and you can't modify what it's testing to do so.
@@anon_y_mousse In COBOL there are keywords for that as well. Namely: "next" to exit all nested loops. "exit perform" to break out an inline perform loop. As always, use all code statements, especially statements breaking the flow of processing, in a sensible way.
I always stay clear of GOTO for two reasons. First, I always assume I'm leaving behind a mess; and second, it seems a bit rude. The second on also applies to returning early from inside a loop.
That IBM COBOL example is bollocks - it's a COBOL routine embedded in JCL (Job Control Language). He's put two things together and sniggered at the result - "I don't even understand what it's doing" - well, that's bloody obvious. At that point I gave up on this twaddle.
Very funny! For GC, I would like to use ”retain” for variables. Every fifth line, or so (maybe like PLEASE, not too much, not too little), you have to declare which variables you still want to be able to use. Other variables will be taken care of by the garbage collector. As an added bonus, this will also bog down the compiler.
Perfect. You can't effectively have more than five variables in scope because you'll have to constantly retain them in sequence. But it's good practice to circumvent this by putting your stuff into a null-type array that can hold whatever. But as the type is lost you have to keep track of memory bounds in another array.
they won't be taken care of by the garbage collector, instead the garbage collector will recognise that something *should* be deleted, and if it's used before it's deleted from that point forwards the function will complete, and when it reaches the return keyword it will put out a runtime error saying the infinitely helpful "variable used before deletion" with the stack trace targeted one line after the place where the function was called. additionally, the compiler will use a utterly random mathematical function (using the hash of your application source code (any and all files in the directory you run the compiler, as well as subdirectories recursively) as the random seed) to determine exactly which lines are required to have a retain. Changing your source code to fix the issue (it doesn't tell you which line should have a retain) will change which lines are supposed to have a retain. For this to still be practical and to have a chance of compiling, it should have an average probability of 1 in 5 (*average*, maximum and minimum are left to implementation) and give flexibility of +/- 1 line from the line it picks.
To be extra evil, you could take a page from HDLs like VHDL and Verilog, where everything is concurrent unless explicitly noted, and have blocking and non-blocking assignment statements. Yes, for their intended purpose, these features make perfect sense. Not so much in an ordinary programming language
No, no, don't even suggest it! Verilog already has a fuckton of race conditions because of that (testbenches, mostly)! Just save them the trouble and turn half the language into stuff that can't be synthesized, and yes, we'll call compilation synthesis because fuck you, that's why.
Or it should be like make and have a separate use of equals that assigns an expression tree instead of a value to a variable. Not quite a function, but almost.
VHDL! A good feature to take from there would be the BEGIN / END pairing, along with the requirement that some blocks end with “END [block type]” but other blocks end with “END [block type] [name]”.
@@PaulFisher To take it a step further, some blocks would end with just "END" and some would end with the type of block written backwards. You can thank bash for that idea, only it'd be like while ... elihw or unless ... sselnu;
I once got a Java codebase that used throw & catch to pass messages between different parts of the programm. It was never run for very long, but once we did, we eventually got an exception queue out of bound exception, which is not catchable, since the exception queue is already full. To fix that issue, you just have to rewrite the entire structure of the programm your working on to not do that, so that was a fun project. I was meant to just add IPv6 support (yes they were doing network testing with Java, don't ask).
Another idea from html, if you have a old school table and you put any tag between the table and the cell it moves the code outside on top of the table. Maybe the compiler can detect if you are using some code in the wrong place and moves it to the top of the function for you.
The compiler should do that for _all_ syntax errors. Move the code by a random number of lines (backward or forward), randomly adjusting indentation as required, until it succeeds at compiling the code. To ensure is always succeeds at compiling, a bug in the indentation-repair logic sporadically converts code into comments and vice versa.
@@BrendonGreenNZL Best part is that way you won't get an error log about meaningful things, but you can still claim (and prove) that your compiler does in fact have error handling. You can thus make very elaborate and fancy error handling. In the safe knowledge that your compilor will do whatever it can to compile succesfully, and thus never actually give an error.
You touch on an important point here, in order to target a wide variety of output file generation (for producing HTML pages for example) BS should support some form of in-line templating where you can mix BS and plain text.
C++ has, depending how you count, up to seven methods of variable initialisation. So I suggest that BS is having also a variety of methods. Additionally, because we strive for a more diverse society, BS should have quotas for each of the method so that no one method is used excessive more than the others.
Unfortunately for your diversity, kindof the point of this talk is to take things that already exist, possibly with some tweaks. I don't know if a language that keeps track of how many times a function is called, and cares about it.
In high school, we used RPGII. In this, you needed to make sure you reference the type of line that was programmed in the specified column. I think it was column 6. These were H (Header), F(File), I(Input), E(Exception), C(Calculation), O(Output). Because this was used on the IBM System 34, we needed to reference where the character started and its length. Each item still needed to be in their proper columns as well, since this was designed to be used with punch cards. Including some of these features in BS would be nice. To convey further annoyance, add contractions like shouldn't. Require long statements to have furthermore, which must be referenced using a combination of superscripts and subscripts.
Since the language is pass by value, you can make it so that the objects are only shallow copied and you have to by hand deep copy the object in every method to make it work because without it, delete would also delete passed value and the return value of the method since its only shallow copied.
Another freakish one, even if a bit arbitrary: Word usually only has simple statements using logical formulars and strings, but can handle nested code by passing it as a string parameter. Though to identify this, the code needs to be capsulated in curly brackets. It aren't your normal curly brackets though, you need to press Ctrl+F9 and it will create a "this is code" marker in the background that you can not copy paste and looks identical to a pair of bold curly brackets. Which will for eternity not only disrupt any attempt to use stack overflow for these formulars, but also force every developer to explain this behaviour in every comment they make if they want to help people online.
I like “unless” for inverted “if” statements. It's useful for checking that inputs to a function are valid; often, the check for that an input is valid is simpler than a check for that it's invalid. So, such function would have a check for that the inputs are valid, and then the rest of the code would be with that assumption.
I agree, it is an interesting alternative when you would otherwise negate the contents of "if". Not a great one if the language forces you to use it somewhere. For example Pascal had its cycles quite weird with `while` and `repeat-until` as options. I think that if BS gets any real cycles, they should definitely use `until` rather than `while` :D
This is universal in anyone trying to translate from one profession to another. For years, I translated between embedded HW and SW groups. The schism was unexpected. Someone has to bring up the first silicon board…with what? Basic understanding on both sides should be required training. SW folks always had to fix HW screw ups and were always expected to make up for time lost by slow HW. Unfair, and I was always defending the SW release slippage.
LOL - spot on. It was like pulling teeth to get someone to describe what they actually wanted. Typical meeting with requestor: Do you need sub-totals? uh - yes I guess so. How about totals? Uh - yes that too. Page breaks on Division changes? Oh yes - gotta have those. Sort order? uh - what do you think? Me? It's not my report. Uh, well, I'm not sure that I understand Sort Order. Exactly what do you mean by that? I tell you what I'll do. I'll just design this report that I think you might possibly want, and then we can just keep changing it until it makes sense to you. GREAT!! You da' man. I'll call you when it's ready. Bye.
You know, if I were designing a language, I would want to make sure the programmer knew what they're doing, so I would require every translation unit to have a declaration that the programmer knows what they are doing. As duplicating that string would suggest the programmer is simply copying and pasting solutions they found on stackoverflow, each declaration of correctness should be distinct at both compile and link time. Runtime checks should ensure those statements of correctness exist by verifying them against a correctness revocation list. Additionally, every compilation of the translation unit should revoke the previous declaration and require a new declaration to be made. To make sure the programmer doesn't lie, this will require a code signing certificate and they will have to register with the Program Correctness Registry and pay a small annual fee.
Here’s a couple features from TI-Basic that I enjoy (the language of the Texas Instrument graphing calculators): 1) Variable assignment is right handed (value -> var) 2) You need opening parentheses (for anything), but closing parentheses are optional if at the end of a line (I believe in certain contexts too, like a list would be { 1, 2, 3 -> L1) TI-Basic also has 1 indexed lists, which makes it even better I think the thing that would make this aggravating beyond anything is just to break as many conventions as possible. For example the white spacing is just so common that the was BS breaks it makes it aggravating. Any convention that would make switching languages easier should be ignored and go in the other direction. Also CoffeeScript actually has some features that are syntactic sugar (which includes unless), but also allows for really lazy programming habits. When I’ve written in CoffeeScript, I generally utilized those shortcuts and it makes code so much harder to read
I’ve worked with a _lot_ of Perl (enough Perl that I’ve seen good Perl). And it had `unless` keyword as well. I generally liked how you could make a piece of code clearer sometimes by choosing one option over the other, but at that point, it becomes as much of a craft as writing good prose for documentation. It really stuck with me that “with great power, comes great responsibility” because like… yeah, it was powerful, but you had to use it sparingly, and only where it made things more clear rather than less clear. Now, I program mostly in Go, and I much prefer the cookie-cutter one-way-to-do-things attitude. Doing similar things always looks similar, which is desirable in a programming language. We don’t need suspense, narrative flourish, and twists in our programming languages, like we prefer in our prose.
Didn't need closing quotation marks, either. Just imagine the trillions of precious, precious finite bytes being wasted on such luxury.
2 роки тому+1
@@puellanivis Perl's TIMTOWTDI sounds like a nice idea, but in practice most shops surely had coding guidelines that boiled down to something resembling Python's "There should one - and preferably only one - obvious way to do it." Because "readability counts" ;-)
I thought this video would be 15 seconds long. Someone comes up on stage, yells "Java", gets his applause and leaves. Glad there was a bit more depth :P
VBA programmer for Access here and proud of it :D (it pays the bills nicely) Though I do enjoy learning other languages. I'm surprised at some of the dumb conventions in all languages though. That said, I love being a heavy Access dev because I have control over the database design (harder than most people think), UI/UX, and code, all in one platform.
I also learned APL in college in thr 1970s. It was what now might be called a cult language. There was a group of us who where dedicated to writing an actually useful program in a single line of APL.
@@gamerk316 as I understand it, it was originally meant to be a mathematical notation, not an actual computer language. One plus of learning it, for me, was it made learning SQL simple.
APL’s advancement was arrays. There wasn’t such in COBOL, ALGOL, COMPATIBLE ALGOL, EXTENDED ALGOL, etc. IBM Scientific Center in Houston, late 1960’s was big on this.
@@gamerk316 --- I used APL on a mainframe, the "IBM 370/148". Most programmers did not know that the IBM machine code (that you coded in Assembly Language) was interpreted (see: EVALUATE in this talk) by "microcode" -- much like processing byte-code that a Java compiler had generated. Some gifted (twisted?) IBM programmer took one of the 256 possible machine-codes, and wrote a pile of "microcode" to produce an APL interpreter that ran as part of the microcode. That "Model 148" mainframe ran APL code faster than the generally-much-faster "Model 158" mainframe, because that APL microcode worked only on the "Model 148". APL was interesting, because it forced you to think about manipulating arrays and matrices, rather than operating on scalar elements. Great, if you could transfer your acquired knowledge to programming of "vector processors" that the Oil Industry needed, to process all their seismic data within a finite number of hours.
btw brackets on function calls in ruby are not optional only in case you're not passing any params, they're *always* optional, and not only that but squiggly brackets around hash literals are optional (and not only that, functions do not support keyword parameters), so eg. "foo 1, 2, 3, a: b, c: d" is actually "syntactic sugar" (more like syntactic acid) for "foo(1, 2, 3, {a: b, c: d})"
I have resisted learning to code since the early 80s, when smarter friends than I got into it and now have big houses. But I can appreciate what he's doing and am laughing out loud at computer programming.
Make it so that programs may (later versions have) rewite Runtime/Compile loop as a part of program. Some languages are extremely flexible (Lisp, Forth .. ) and can do plenty neat things. I was kinds surprised not to hear much of Lisp or it's variants. Those can make life interesting like making self modifying high level code.
This video should be used in job interviews when you're looking for a software developer. The more the candidate laughs, the more he knows how to code properly...
An assembly programmer would not understand any of this. The fact that his code ask to Delete local variable is proof that he does not understand how things actually works underneath. local variables are on the stack they don't get deleted, just ignored and overriden eventually. When you sp = bp (stack pointer = base_pointer) nobody cares it is a stack.
@@MarquisDeSang Perhaps the requirement to Delete local variables is a security feature, it overwrites the data just in case you stored anything sensitive there.
@@dave7038 Yea a random sequence of numbers written on the paramaters of the stack multiple times to wash sensitive "counters values" before exiting. Brilliant. lol
Even better: do memory management like taxes - there is a GC that knows exactly about things to delete, but you still need to manually predict what it would do - and the program crashes some time later if you forgot.
excellent idea and it would have been a wonderful criticism of the tax system at the same time
Valgrind :D
This is the most chaotic Idea that I want to see in a programing language.
This might also help make programmers understand that memory can be a limited resource too 😆
@@SeleniumGlow Free? What is that?
@@MrRyanroberson1 I don't know, tax system where I live works just fine. :)
I once used FORTRAN on a Harris computer. It was possible to declare identifiers with numeric names. So you could have an integer variable called 3, and assign it the value 7. From then on, 3 + 4 would equal 11.
So easy to sabotage somebody's code by slipping in a declaration like that.
That was with PL/2.
I remember the Harris. We had one at Norwich City College - took up several floors!
Dear God, that is despicable!
Harris! Now that is a blast from the past!
So what you're saying is we should allow numeric variable names _and_ remove €-prefixing for specifically numeric variables.
In many cultures the digits '4' and '13' are considered unlucky, so to avoid offence, the compiler will generate an error whenever it comes across these characters. Programmers will be expected to code expressions to avoid these values. Eg, "5-1" and "15-2" would not cause an error. Note that representing 13 by 14-1 would also cause an error since it contains the digit '4'. And there would be no builtin constant for Pi, so programmers would have to come up with their own ways of writing 3.1415 without using the digit 4. Variables that contain the character '4' or '13' would also generate errors. And to make the language kid-safe, it would also generate an error for '69'.
I love this.
Ban '420' as well
@@jan-lukas Yes, sorry I missed that. Perhaps the full list of offensive numbers needs to be configurable. I recall now that someone told me that in Vietnam the number 1 is generally considered offensive, such as in "He's our first born child, our number one child." So perhaps Pi could be written as 3.36359-0.222 (without a 1 or 4 or 13.)
Ha ha, such nonsense I didn't come across yet, but who knows ?
I think you got a good idea there, but I'm also thinking PI should actually be in the language. But preferrably as 6.2830... like was suggested back in time when they were thinking about pi. Or just make it 3.0 like some people suggested to make it easier. Because that's a smart thing to do.
Hello, I 'd like to say I've fallen in love with BS, and am working on an interpreter for it. Unfortunately, I couldn't get static analysis to work reliably for DELETE, so I added a garbage collector.
Now don't get confused, it's not a collector of garbage, but a collector that IS garbage. It works by clearing all memory every 13 lines unless specifically asked not to do so by writing the line "NOT YET", the space is part of the keyword.
Now I do want programs written with my tools to be compatible with yours, so you still need to DELETE all variables, however my interpreter will only be able to warn you about 5% of missing DELETEs, by crashing at runtime.
you should totally add custom infix operators like in haskell. and allow programmer to shadow any system keyword and operator
Brilliant!
Where is the language standard's or compiler's repository/wiki? I would like to fill in some feature requests :)
... like partial pseudo randomization of operator precedence... at run time
@notfiveo and who are his audience?
To be fair, if you can't implement BS in it's purest form, then you should consider the project a fork of BS and call it BS- instead.
That is SO EVIL
It's not really a programming language, but when maple gives you an error, rather than give information you can use to correct the error it gives you a hyperlink to the relevant help page on their website, many of which simply read "a help page for this error does not yet exist."
It would be even better if it just returned a 404.
And randomly a 503.
Had me in the first half.
// TODO (Which in Spanish means ALL)
That's the same strategy Microsoft uses for the help sections in Windows Settings. It's annoying (not least because it always opens a Bing search in Edge, not just a hyperlink to the page in your default browser) but not a huge problem all the way up til the time the problem you're trying to solve has to do with internet connectivity. Ask me how I know.
@@traveller23e ok. How you know ?
Something I admire about ancient COBOL is the ALTER statement (ALTER labelname1 PROCEED TO labelname2). This has the effect that if you have a "GOTO labelname1" somewhere in your code, it will jump to labelname2 instead (after the ALTER statement has been executed; before that it'll jump to labelname1). Maintaining code with more than one ALTER statement is a horror, which makes it a perfect candidate for BS.
Computed GOTOs from Fortran, like GOTO X*2+1
@@InXLsisDeo @rjeninga Why not both? Computed ALTER statements, like ALTER X*6+1 PROCEED TO X*7-2
I like the alter but another COBOL example is PERFORM x THU y..... Some unsuspecting soul puts some code in between those parras... get's well... a present. You can add the optional "x TIMES" on the end for a good and proper job.
I wrote hundreds of COBOL programs for several companies; GOTO (except error-exit) was strictly forbidden throughout. You can do structured programming in COBOL!
@@MarkRendle Thanks, I hate it already.
They should definitely take a pillar of programming from the world's fastest embedded language, Lua: Variables are part of the GLOBAL scope unless specified with the "local" keyword. So if you typo a keyword, it won't error, it will instead create a global variable by that name. This will "reduce" compiler errors and maximize fault on the programmer themselves!
E.g.
function Check(€val isMaybeA Number)
42 CRASH_AND_BURN
unless €value !!=! 5
Delete €vall
Creates global variable €value
Doesn't throw exception even if €val is 5
Creates, then deletes global variable €vall
If so, I like it 😁
Sounds reasonable.
And the best way to check that is to compile it with -s, then decompile it, and search for variables that aren't Lx_x
@@phizc And then crashes because you didn't Delete €val and €value.
What brain dead designer thought it would be better to introduce a runtime bug than to catch the error at compile time? In what fantasy world would introducing a random global variable be preferred, just so the darn thing would compile (but not work)?
Thought he was gonna talk bout JavaScript
But enough about languages that suck, let's talk about JavaScript.
I mean... that's why typescript exists
Weird way to say python.
@@BestSuper wierd way to say Visual Basic
@@gdmathguyDoes typescript alert you when you are making a memory safety error not documented clearly, that doesn't even give you an error massage at runtime, it just doesn't run it‽‽‽ Or can it fix self contradictory documentation?
PowerShell has a "Verb-Noun" naming convention for function names, where the noun should be strictly singular, and the verb should be selected from a list of approved verbs. If your code doesn't comply with this, you'll get a warning from the linter (at my previous workplace it was enforced in the validation process). BS should adopt this with a twist: The compiler should fail, whenever it finds an uncomplying function name, and the list of approved verbs should be undocumented, and left for the programmer to figure out.
8 years in and we're still finding easter-egg verbs accepted by the devs XD
@@mr.rabbit5642 Can you share some, I'm curious?
I completely agree with you, except for one thing.
It’s spelled: PowersHell
To be fair, I genuinely love the Verb-Noun format for PowerShell functions. It's not strictly required, is more commonly "Verb - compound noun/specific descriptor", and you can find the approved verbs with the command "Get-Verb".
After using it for years, I always use the same format without the hyphen in all languages as it makes the method self-descriptive.
@@1992jamo Yeah, do the same in Java, just it tends to elongate names sometimes.
I noticed that the string interPOLation used the dollar ($) symbol and not the Euro (€). I think using the symbol for the Polish Złoty (zł) would be more appropriate.
@jernejj5 I think it should be dependent on your region, but always giving you the most annoying one, like for EU use ¥, for US use zł and so on. Obviously has to fail if you run it in another region.
@@artemis_fowl44hd92 Code region locking, DVD style. Of course, for customer convenience, trans-regional transcribing should be offered as a service. €100 per variable mention, including the ones in comments and "Delete" statements.
Wtf! Lol
The Euro didn't exist back then
@@tomlxyz If the first talk was in 2014 (As said in the video), the euro did exist 15 years.
ideas from MS-office: some instructions should be localized. i.e. goto, gehezu, allerà ... depending on the OS's language. This should also fail for executables, if you run an english EXE in france, it should fail with "goto command unknown, did you mean allerà?". Also depending on locale, the meaning of "," and "." should be swapped, not only in numbers, but also everywhere else in the language.
That error is too helpful. At best it should be “Unknown Command”.
@@endymallorn Nah, just extract a random keyword
How about "AN ERROR HAS OCCURRED" ? The error could be one of:
(a) there is a bug in the program; or:
(b) the run-time code has erroneously decided that there is an error.
HOWEVER, and independently of the above, there is also the possibility that:
(c) a genuine error has occurred, but the system has failed to report the error. Naturally, you have to use your psychic powers to discover that this error exists, where it is and what it is.
No error message whatsoever, just restart the PC if something goes wrong. Of course there is no errors log too
you sick fck.....i like it.
The idea of allowing anyone to upload an image that can then be downloaded as a "UTF-256" character sounds like something a startup might actually do.
@@BenjaminBrienen That's the point of the joke, dummy
@@gellertli2916 you'd still need some service which holds a masterlist of source content indexable by hash, otherwise you'd need to run a bank of GPUs to hell and back to figure out what to display- oh my god that should be a design feature.
still better than NFT logic!
@@vanesslifeygo Hm, not better but different. You can store the unique characters in the blockchain so noone else could modify them later on.
And since the ladder is decentralized there would be no single owner of the whole "database" either.
I like the idea of identifying each LLC with its UTF-256 character. So, to transfer a sum of money or an NFT from one LLC to another, one UTF-256 to identify FROM, TO, SUBJECT, CURRENCY or object type, and quantity. And no error checking, If a bit error means I now own the GDP of China or Elon, oh well. And all timestamps indicate the transaction occurred in the distant past, so any possible statute of limitations has expired. Wait. Should I patent this?
The "feature" I hate most in Excel (as far as the code in excel is programming) is that function names localize to the computer language. So if your computer happens to be set to dutch, or german, or norwegian, or whatever you can't following English language tutorials.
Microsoft even created a function translator you can download in the latest versions of Excel to fix that.
If you choose to make BS interpreted, localize the functions to the language of the computer running it, so you need to offer a version of your script for every language computer.
Excel references are "come from" in two or three dimensions.
Not just the function names, but also localise the variables. You have to use dot as a decimal separator on English computer but comma if your computer is set to Czech or German. Even better if declaration of strings had to follow local quotation marks rules...
Oh god, I hate this "feature" with passion. I have set Excel on my machine to English to make it easier to work with.
omg yes! This was the worst! Why, Microsoft?!
@@arnes12345 VBA was localized in Excel until 5.0 -- which made it hell/unusable. Imagine "sub test()" would be "subrutine test()". "Option Explicit" would be "Alternativ Mådeklarerevariable" WTF!! Still I'm struggling to help my coworkers that have Norwegian Excel as formulas are Norwegian! So formula =VLOOKUP(lookupvalue; range; index) must be =SLÅOPP.RAD(lookup etc etc) I want to slap the programmers with a soft pool-noodle :D Could they just not make it multilingual???
Another suggestion from Lua: all variables are global by default, you have to remember to put the “local” keyword every single time if you don’t want weird bugs and memory leaks.
And require the "global" keyword for all variables at global scope and add "local" to the front of that to designate module scope for a global.
Lua... Why!? I feel bad for a lot of kids programming in Lua.
@@anon_y_mousse Sounds reasonable. It would be great to have some syntactic sugar to spare the poor programmers from typing though (errors can happen during typing), so I'd like to see some syntactic sugar like "glocal" for "local global" and "lobal" for "global local". The portmanteau type specifiers follow Reverse Polish Notation, which might confuse a new comer, but fuck them.
@@Anriuko I love it.
But make them truly global, like a a centralized server keeping track of the global variable and its current value, we might run into problems in the future when we colonize other planets though
My first programming language I learned as a kid was Pascal. For a long time I couldn't use "else" because the compiler would always return an error whenever I used it and I couldn't figure out what was wrong. At first I was thinking, maybe I have a weird old version of the compiler that doesn't know the word "else", but then I found someone else's programs that I somehow got on the same floppy with Turbo Pascal, peeked into them, and they were using else and it was all right. But I kept getting the same error, so instead of using else I had to close the if section and open another one with the negated clause.
Only after a good while I realised that THOU SHALL NOT PUT A SEMICOLON AFTER THE COMMAND THAT PRECEDES ELSE.
we're learning pascal right now in my college course lmao
@@martinjoster3282 Pascal is a good procedural language for teaching.
@@martinjoster3282God WHY?
On the bright side you could make your own Inno Setup installers with PASCAL script! when life gives you outdated lemons...
@@worldseriesofghosts3408 Probably a leftover from earlier days, but the idea of the course is to teach general programming logic and structure to be applied to other languages, and honestly Pascal doesn't seem like a terrible choice for it; it's got the base structures, and something like Python has a lot of conveniences and simplifications which one won't always find in their programming journey
you wouldn't see that problem if you by default used 'BEGIN ... END'
I'm scared to think of what horrors the (clearly battlescarred) audience would have come up with, given more time. Every suggestion gave the reaction of "That's so evil, I love it".
The best I could come up with is requiring any valid source code to be hashed and minted as an NFT by BSCorp in order to compile successfully / without a You-wouldn't-download-a-car--esque warning
I spent the whole part about useless variable prefixes waiting for him to announce that the prefix actually does something, like in Ruby. Maybe something like "€ prefix means it is heap allocated, ß as prefix makes it a stack variable." Of course, assigning a stack-allocated var to a heap-allocated one (or vise versa) doesn't work, you'd need some kind of special syntax to convert between them. Would make refactoring fun.
Edit: Oh, I've got it! Converting between head and stack allocated variables can be done by calling a function (or a parens-less keyword) called convert with the variable to be converted as an argument. Of course, error handling is important, so calling this function/using this keyword would inject your current namespace with a head-allocated variable called "okay" (or something like that) which YOU are responsible for. So, everytime you call convert and forget to Delete okay;, you are leaking memory. And of course, okay contains a string, not a bool or something sensible like that!
I suggest that we use both of Japanese's quotation mark sets instead of parentheses, so that nested parentheses need to be given different characters like they do in that language.\
Lets us add 4 additional characters to our expensive keyboard while we're at it. I like it cause it would almost be useful if it weren't so annoying, and because it fucks up character spacing.
i.e.:
「unless 『€i !!=! -1』」;
Edit: more than two-layered nested parentheses should alternate:
「unless 『「€i * 2」 !!=! -1』」;
thing is with a language like this you have to be careful not to dip too far into esolang territory, instead taking inspiration from bad design in non-esolangs. What you suggested is something I'd expect more from malbolge than the language described in the video.
I'm just thinking: use the scoping rules of python and javascript combined.
"this" will just go out of scope at random. Reading from the previous scope is permitted, and will bring the variable into the scope, but writing to a variable from the previous scope is not permitted, unless you ask permission first. Variables with the same name will hide access to the previous one.
Oh, and loops will not introduce a new scope, but functions will. So for BS, let's say that goto-statements create a new scope, but line numbers do not by themselves.
@@tokeivo I like those ideas except 'this' going out of scope randomly, as it doesn't feel very fair or programmy for it to be random. Instead perhaps something similar to INTERCAL's 'PLEASE' where the rules for when it does and doesn't go out of scope are rigid, just not documented anywhere (like every 21st 'this' in the source code is in the global scope)
From BASIC, the language should require line numbers to be part of the source code. It has the advantage that you can move lines around without changing the execution flow of the program. That way, lines can be sorted in a way that are the most aesthetically pleasing.
I get the sense that line numbers are a holdover from when terminals could only display a single line. So... you should only be able to use ed to modify BS programs.
Sounds reasonable.
This is where BASIC is similar to machine code
@@b213videoz First, modern BASIC doesn't require line numbers.
And second, the line number is not comparable to the it's instructions address, so it's not comparable to machine code. I mean, unless you were considering line numbers to be labels... which is what they were in the dark ages of BASIC.
Aesthetically pleasing? No, they shoould be sorted alphabetically, otherwise it's compile error.
The use of UNLESS is genius. Rudolf Flesch who wrote "The Art of Plain Talk" remarked that sentences which contain "unless" are among the most difficult to understand.
I wonder about this. I've always found "unless" and "until" pretty readable in Ruby.
u sure it wasnt USELESS?
To be fair to Ruby, "unless" (and being able to put it at the end of a line) isn't actually original to Ruby -- it originates in Perl, which Ruby actually takes a lot of inspiration from
You forgot one of the best ones. VB6 (and VBA) use Bankers rounding. So 5 is rounded up or down depending if the next most significant digit is odd or even. But that would be far to easy ... BS should round up or down depending on if the line count is odd or even.
Sounds too simple, the Douglas Adams principle should apply here as well. If the round function has been used for the 42nd time, then we round the number the other way than expected as we see for the other 41 timeas.
Brilliant....
Yes. That would compensate for too many roundings in the wrong direction!
@@gorillaau No it should always round to the nearest multiple of 42 and then invert on the 42nd call
x 69, / 42
MATLAB is a treasure trove for this.
- forgetting a semicolon at the end of the line will echo anything
- Round brackets are used both for function callings as well as array indexing
- You can use [] or {} for array indexing as well, however, their behaviour and rules depend on the type of array you are accessing, and they are NOT interchangeable.
- 'a' is a character array, but "a" is a string. Completely different things.
- The + operator on character arrays will treat them as vectors, performing element-wise addition of the ASCII values of the characters and returning a new character array. If the char arrays have different lengths, it will crash.
- On the other hand, the + operator on strings will concatenate them. What happens when you + a string with a char array? I can't remember, and that's an issue.
- Built-in functions have inconsistent behaviour with regards to strings vs char arrays. Most (but not all) will will accept either as arguments. Some (but not all) will return the same type you gave as input. Many (but not all) will convert strings to char arrays and return char arrays. How can you tell how a built-in will behave? Not from the documentation, because that would be too easy. Fire up your matlab instance, re-activate your license for the 15th time, wait for the IDE to spool up, and try it out!
- And so, so much more...
And the most crucial - array starts at index 1
Another “great” Matlab feature: logical variables aren’t “true” or “false” but 1 and 0, which are not to be confused with numerical 1 and 0.
But it is the easiest language to learn imo. Having it as your first programming experience makes it hard to learn other languages tho...
coming fresh out of a Matlab course, this is painfully accurate. The only worse thing is trying to find a reason to use Symbolab!
[1 -2] is an array with two elements, [1 - 2] is an array with one element.
I'm a mechanical engineer who knows just enough about programming to know that this is hilarious and would be infuriating to use. It reminds me of a time in school a couple years back when I was talking in some of my classmates about "Anti-CAD," similar concept for 3d design. Points had to be circles with zero radius, threads had to be made with a virtual tap or die tool (which had to be turned the right number of threads with the mouse)... I forget a lot of the really funny/annoying features but it was a good comedic break from serious study.
All 3D cad objects must use completely parametised 2D sketches before it can extrude. Then make parameterisation break with anything outside the smallest adjustments.
Or Autocad light where parameterisations are behind a paywall.
Or do what SpaceClaim does and make all basically all 2D and 3D operations pushing and pulling the sketch with the mouse.
33:56 In Norwegian, there are three gendered indefinite noun articles (in addition to plurals), and so the compiler can also throw a cryptic grammar-checking error if the noun doesn't agree with its gender.
Of course you then need to know the gender for any custom type, so programmers will have to specify the gender of their classes unless the class name ends with a word from a dictionary built into the compiler, in which case specifying a gender is obviously invalid.
If you're going to do that, then why not force conjugation of the various commands so they agree with their subject (singular, multiple object operations), tense (imperative, timeframe), and mood (likely branch, unlikely).
And at the start of any program, you must put in a declare block, outlining the declared pronouns for every class & function in every scope. Any he/him function is sent to die, every she/her is considered hysterical and ignored, and any they/them is considered plural, requiring the use of areProbablyA. And if you don’t include at least one gender with an x in it, the program throws a bigot error and refuses to compile.
Make the whole language strongly inflected, like Latin.
Well, that depends on if you speak bokmål or nynorsk. Norway has two official languages.
What you can also do for comparison is that when comparing with undefined, the result is not true nor false, but undefined. When checking for equality with null, the result is not true nor false, but null. And if you check that undefined is equals to null, the behaviour is undefined and produces random result each time.
Inspired by SQL.
For absolutely no fathomable reason, `undefined !!=! undefined ` should evaluate to _true;_ and `null !!=! null` should evaluate to `undefined`.
@@BrendonGreenNZL what did you just type
@@SreenikethanI Yes.
Sounds reasonable.
In SQL null is not a value. It's the lack of a value. Therefore comparisons with null doesn't make any sense, including comparing null with null
Guys! There is an obvious oversight! Just like in JavaScript, “this” should not always be “this class”. It should sometimes be some random object in memory, depending on what time the code was run at! Amazing debugging sessions!
Sounds reasonable.
I like the idea that "this" in a class will act upon the class itself instead of on the instance, unless in the __construct method you call some function built into classes implicitly that isn't documented anywhere. Something like `this.createInstance()`.
If the __construct is called via `super()` then it will skip over `this.createInstance()` meaning EVERY constructor must call it and it must be called before any super calls, which will directly conflict with "no this access before super", meaning inheritance is implemented but utterly impossible at compile time.
was so struck by this gem the last time I watched him give this talk that I called it Rendle's Law:
"There's nothing you can suggest that is so unutterably stupid that people won't waste their time attempting it"
i like this
hell i even love this, rendle's law is in my vocab
My Idea: every type should have it's own "null" type. For example: "NotString" for string, "NoNumber" for int, "MissingFloat" for floats etc. The less consistent the naming, the better. And of couse, no easy way to convert between them.
I think this would be a *good* idea. If it's a bad idea, is having separate 0, NULL and "" a bad idea too?
theres a general isNull function but it depends on the phase of the moon and the average temperature in mauritania.
The MissingFloat type should be just called 'Sunk' for clarity.
@@user-vn9ld2ce1s therefore the isnull function for floats should be called battleship?
@@unflexian Perhaps... Or just Get_Density()
Awesome. I think the Delete should have a safety feature borrowed from operating systems. Delete doesn't delete anything, it puts it in the Trash (or recycyle bin if you're on Windows). So, Delete all you want, that space in memory is still in use. You need a second step to reclaim it.
I might actually put that in.
You could actually use this to return values from functions, the caller uses UNDELETE to retrieve the last value(s) that the function Deleted. That would mean the caller had to know the order of Deletion, making the code extra brittle.
@@MarkRendle RUNDELETE to do a Reverse UNDELETE in case you wanted the first item ever Deleted (but since the trash has no scope, it could be anything that was deleted)
No. It should work the way ANSI C manages memory. You delete everything, including the whole partition, without any warning.
"COBOL was made so business people can write their own applications the way they want. But they can't even describe the business programs they want, much less write them"
*Java slowly edging towards the door*
progress openedge enters the fray
@@Akronymus_ I googled this, and immediately regretted it. thanks.
COBOL was written so that it could be compiled on very small machines for the time, and of course also on the larger ones. Thus, a source program was divided into four DIVISIONS to establish, before seeing the procedure code, the more global metadata about the program. The IDENTIFICATION DIVISION gave the name of the program, who owned it, when it was written, how to handle security, and any other administrative information, including a tutorial on how it works.
The ENVIRONMENT DIVISION told what special options the computer must have, and how to allocate input files to actual hardware.
The DATA DIVISION described the layout of each file and its data records, and the name and layout of each working memory data variable (and in later versions, the names and layouts of parameter records passed from the calling program).
And the PROCEDURE DIVISION contained the actual processing logic statements.
The compiler could therefore be built in overlay phases for small machines: the first phase only had to be able to parse the IDENTIFICATION statements; the second phase, only the ENVIRONMENTAL statements; etc.
COBOL restricts program variables from duplicating the spelling of reserved words so that, in putting out the temporary source code, each token could be converted, in smaller machines, into a compressed form, such as an index into the symbol table being accumulated; reserved words would be an index into the reserved word table, etc. to make compiling on really small machines possible.
And also, it was intended to allow managers to be able to read source code and learn how each program fits into the customer’s library, with minimal or no explanation from any programmer (thus, it could be written to be “self documented”).
FORTRAN originally had no syntax for saving the result of a comparison (the IF statement tested a single number (or expression), and designated a specific statement number to go to if it was negative, zero, or positive).
FORTRAN IV introduced Boolean values, of which the value of a bit was represented in the program as “.TRUE.” or “.FALSE.” The comparison operators were “.LT,” “.LE.,” etc. and the combining Boolean operators were “.AND.,” “.OR.,” and “.NOT.” This was because the character set was very small.
FORTRAN also used statement numbers instead of labels, but not every statement needed a number, and they did not need to be consecutive.
COBOL was horrible. It was built on the premise that somehow "ADD 1 TO COUNT GIVING COUNT" was easier to understand than COUNT = COUNT + 1
@@cadaankaa For some folks it is. But it also allows ADD 1 TO COUNT, which is shorter and easier to understand than COUNT = COUNT + 1. And it also includes long names, so you can, for example, write MULTIPLY TIMECARD-HOURS-WORKED BY EMPLOYEE-HOURLY-RATE GIVING OUTPUT-GROSS-PAY. This was good for reading and understanding programs written by other people.
In some math classes I would see the teacher alternate between () and [] when nesting parens. Why not do that in this language? Something like
a = (b + 3 * [6 / (2 - c) ] ) / 7;
If the parens don't alternate correctly, "syntax error. press any key to continue." and the compiler waits for the response before exiting, making automation of compilation just a little bit harder.
If someone wants to add something in the middle, they have to change the inner and/or outer parens to alternate correctly.
let's make the outermost level have to be (). That way if they want to add another level on the outside, they have to change everything inside.
also, let's make / and * evaluate from right to left, so to get the natural interpretation they have to use parens.
evaluate all * before all / so it's even more confusing. Cite PEMDAS if anyone gripes.
use e as a keyword for exponentiation, but not like everyone else uses e. 1e7 should evaluate to "1 to the 7th power" instead of "10000000".
That is evil. This is the right addition.
That actually makes good sense, it should be like this
@@tabooretka Confusing things was the point. We are trying to make the worst programming language ever.
I even learned at school to use curly braces on the third level like ([{x}]).
Nice, but in a future revision we should consider matching different types of parens thus: (b + 3 * [6 / (2 - c] ) ]
I would also like to see + and - have higher precedence than * and /, and - have higher precedence than +, unless we're calculating array indices in which case it's reverse.
I also think the semicolon could be overloaded as an arithmetic operator when next to a number literal, casting the number into a semi-float. It could potentially make the language so expressive.
Index Origin: Most languages start counting from either Zero or One. BS sets the index origin to simply -1.
APL allows one to dynamically set and modify the index origin to either 0 or 1.
So separate threads may have different values, or the value may vary within a loop, or different functions.
However, if the index origin is undefined in the code, APL uses either 0 or 1 dependant on the users predefined preference, so the value will depend on who is running the code rather than who wrote it.
Na lets start rge array at -0.5
@@poltergeist9972best I can do is -sqrt(1.01)
Conscientious programmers set ⎕IO to the required convention in local function scope. This barely dents the gyrations one performs as a conscientious shell programmer.
Why start at just 0 or 1? Why not OPTION BASE 42?
@@poltergeist9972 Yeah, why can't arrays be fractional anyway? That's should like a good idea to me.
Allow me to suggest a better way of implementing multithreading:
The GOTO statement accepts multiple line numbers. When you give multiple numbers, the process forks with each child process starting from one of the line numbers given
For example, GOTO 42 84 spawns two processes - one starting from line 42 and the other from line 84
I like that idea
Looks like elixir on meth
lets do a step beyond!
instead of goto, lets have a COMEFROM multi threading just like intercal
you can put a COMEFROM anywhere in your program, and when it reaches that line. it starts execution from the COMEFROM in a new thread... without any warning in the code that is actually running at the time
it should be GOATO (the A is for "asynchronously") pronounced the same as GOTO so it's impossible to disambiguate the two when speaking
@@JordanManfrey And all functions should be async by default for performance like in Express, so you need to wrap and await everything to make it synchronous.
I suggest that your DDE (disintegrated development environment) should treat tabs as four spaces but display them as three.
While I understand the idea behind an odd number of spaces being a comment, I also like the REM function, which made BASIC have to evaluate comments while running. It does so much to improve (lack of) efficiency.
A few ideas:
- have error message line numbers also made -1-based (and column position starting at the end of the line)
- you have classes, so make the inheritance dynamic and easily overridable to any other class in the program. So you can easily access a field in a random class even if it's private, by quickly changing the base class to that, read it, and set it back to something else.
- you did not play with #pragma... there should be one that rounds every number to an arbitrary low precision (eg. constant Real_Pi !=! 3.1 when the file has #pragma MediumPrecisionON somewhere on the top). Also, when using '#pragma SECURE' every identifier needs to have minimum 8 characters, an uppercase, a digit and a special symbol to be valid.
Sounds reasonable.
Yes, the language should definitely not allow immutable data types of any sort. The values of variables should spontaneously change if the programmer neglects to set them within a certain time.
1. Error messages should be based on number of characters before (or after) the line where error occurred.
2. R language will change the type of your variable on the fly, if it cannot process the inputs properly, say to a matrix.
@@RobinHillyard this should be a well-known variable rot feature, hahaha
Of course, BS is secure by default, so that's the default. You need #pragma INSECURE before declaring any identifier that doesn't meet those requirements.
First rule of programming: users don't like errors. In their endless wisdom, the developers of Visual Basic invented ON ERROR RESUME NEXT, which wraps literally every statement in an error handler that just silently swallows every possible exception. Even if the complete code is totally unusable due to some null reference error in the very first line, the user must not be bothered by annoying messages, especially with scary stack trace information.
In BS actually this should be the default behavior. Though it makes it a bit harder to identify the root of the problem, the user will not freak out, maybe just notices that something is slightly off.
Of course, there are some serious cases when crashing is the better option. So I suggest an UNLESS CRITICAL extension to the command, which may enable crashing in some circumstances. Judging the "criticalness" must be left to the executing runtime: even the same error might be considered differently, depending on some parameters such as the temperature of the CPU, for how long is the app running, etc. But even when crashing, no scary debug information must be displayed to the user.
Basically how to never find out you missed an error.
There's already a language that does that as much as possible - it's called PHP.
I think powershell has that option as well.
this is an amazing idea for part of this,but the second half is just ehhhhhh
@@lpfan4491 He said BASICally
5:40 COMEFROM is actually not semantically identical to GOTO if you allow to use multiple COMEFROMs for the same source. This way you could've introduce non-determinism or parallelism in some way, however you define the semantics.
This is brilliant
yes. I kept finding myself wondering how old the speaker actually was, especially during the INTERCAL part. COMEFROM was one of the more subtle jokes in INTERCAL, and I think you needed to be involved in the language debates of the day to truly appreciate the commentary contained in it
Perfect! That's how threading should work! Maybe it'll be nice and also continue to the sequentially next line too.
Ooh - new multithreading model maybe?
COMEFROM should start a new thread every time it is used to reduce overhead.
Though since there is no GOTO, every time you use COMEFROM and don't want a new thread you will need to end the program immediately after the line you are comming from and let it continue in the new thread.
Variables should leak out of scope like in python. By default, you will use the identically named variable from the outmost scope, but Local keyword can be used to use the innermost scope instead. Be careful not to Delete the outmost scope variable, since those scopes will start using the next outmost variable instead (which was probably the Local variable you wanted to Delete).
Biggest reason I hate python
@@SuperDudu72 pretty much, except so that it works in a way that's less logical
OMG this is the second least favorite Python feature of mine, after significant white space. We should definitely have it in BS, it would be brilliant!!
there seriously is a bs language - developed by someone at AT&T Bell Labs back in the 70s. Can kind of think of it as the Perl of the 70s. But seems to not gotten any traction and faded into obscurity.
I have a 9 page manual for it: "Bs is a remote descendant of Basic and Snobol4 with a little C language thrown in. Bs is designed for programming tasks where program development time is as important as the resulting speed of execution. ..."
Interesting. Apparently, at one point UNIX featured bs as a language on par with C, Fortran, and assembler.
@@fllthdcrb SNOBOL4 was big on the IBM mainframes like the 360. It came out in mid 60s (in a portable version that ran on a virtualized machine - implemented with assembler macros). It was adept at string pattern matching so it may very well be the granddaddy of regular expression grep-like libraries and tools
and clearly, per that blurb in the BS manual, the folks at AT&T Bell Labs were aware of SNOBOL4 so perhaps that is indeed what they drew on as inspiration for the the regular expression capabilities that they made famous in tooling, libraries, and languages (well, Perl was Unix inspired and had integral regular expression capability)
@@TheSulross SNOBOL4 was a useful language - once you got your head screwed around enough to deal with its syntax and got used to the 'space' as being a significant character. I think the Griswold, Poage, Polonsky SNOBOL4 manual was the worst I've ever encountered: useful only if you are already intimately familiar with the language. I spent a lot of time reading the Index line by line, looking for something suggestive of of what I thought I needed.
@@walterpinkus5534 I recently listened to a podcast on SNOBOL and it seems it was mainly a thing on mainframe computers back in the day. The Unix world developed it's own approach to reg-ex tools and capabilities (unclear if they drew on inspiration from SNOBOL - which had been around since the 60s) and that heritage for reg-ex text processing is what survived into the contemporary computing landscape
A lawsuit already.
I am not sure why, but this talk made me laugh harder than any comedy show ever has... Thank you and I kinda wanna write a BS compiler now xD
Please Do
There are worse or better uses of your time. So I guess you have to be certain that’s precisely how you want to waste your time.
Compile your BS yourself
I saw his first talk like this, I think it is 7 years or so ago. Also just as funny - this is just the updated one 😃
Edit: i was close - ua-cam.com/video/hCvHTrUh4os/v-deo.html
If some of you want to participate or look it up, I'm working on one at BS-parser in github
You have to put in pointers as most people are really confused by them. But instead of being a variable pointing to the memory location of another variable, a pointer in BS stores the line number the variable is declared in. In order for this to work, the variables you want to point to have to have line numbers added during compile time, of course. In code, you then get the line number a variable is declared in using the FoundIn keyword.
Dereferencing the pointer is very intuitive and works as follows:
You create a string containing code to GOTO the line number with the variable declaration, then get the sourcecode of this line using GetCode and use RegEx to modify the line to not declare the variable but read it's value. This code is then executed using EVALUATE so you can also use pointers in a multi-threaded environment.
Suggestion: From Shell script, go for -gt, -eq and >, == depending on whether the comparison is numeric or not.
@@weakspirit_ In Hypertalk, the programming langauge invented in the late 1980s for use on a Macintosh program called Hypercard, there was no cleanly-identifiable distinction between strings and numbers, and the comparison operator was non-transitive. '5' > '14x' > '12' > '5'. Javascript can be about as bad when compring strings and number objects, but at least in Javascript a string comparison between "12" and "5" will report the latter as greater. In early Hypertalk, the only way to force string comparisons would be to prepend a constant to both strings that would prevent either from being interpreted as a number.
I vote for invisible implicit variables, like *$_* in Perl. When reading code code you have to remember every circumstance where they might appear (or rather, _not_ appear).
As long as you remember to Delete it when you're finished with it, of course.
During runtime, your program should initialize a "registry". Every time you create an object the program should assign it a GUID and insert it into the registry, and return the GUID value. Anything that isn't a basic data type should be stored in and retrieved from the registry, including classes, structs, and arrays, and their GUID is stored in the program using the new GUID data type. This way you can limit those annoying custom types, because they get in the way. Names and internal data are still important, though, so you can store that all as subkeys. This is great because you aren't forced to follow the defined layout of a class like all the top languages force you to, and you can even do it without defining a new class extension!
Registry initializing should be done at compile time, run time would require the registry initialized. This way you can't move the compiled program to another machine unless you have the proper registry keys. Registry keys should not be grouped under a single root but rather scattered all over the place under the sha256 hash of the class (struct, array) name.
@@joseluu260 I like this a lot, but I fear we need some more security and we should also require keys to use our language. We can't have random people using our language for who knows what! This way we can also include the user information in the hashing and make it so your code only runs on your computer, even if you initialize the registry keys. You know, for security.
A Greek semicolon is actually just the top dot from :
I think a better option would be to combine with Spanish and always pair punctuation with the opening mark being upside down 🤣
Even better:
Make it MatLab (but in Spanish) (yes, that's it's actual name "MatLab (but in Spanish)")
If you forget either the opening or closing punctuation (unless constructs require one at the very start and at the very end) the ENTIRE construct is evaluated and printed before the condition is evaluated and the branch taken is evaluated a second time (including all side effects)
Open questions:
What happens if there are early returns in either of the branches?
What happens to Delete's in either branch?
Bonus points:
FOR EACH missing punctuation both branches are evaluated and printed...
Missed the first? That's 1 evaluation for both + 1 for the branch actually taken
Missed both? That's 2 (!) evaluations + 1 for the actual branch!
@@reinei1 Matlab (but in Spanish) sounds like Excel macros.
¡This is brilliant?
As a coder since 1995 I was crying tears .. best stand up comedy for code nerds
Absolutely. A real draw to get coders to conferences. A head liner….can you tell I am an ex programmer who slipped into marketing dev tools? Hey, I am always trying to convince business degree marketers WHY they can’t use “user friendly” in every single ad…to use info that has context.
Who would have thought that a Computer Science conference could be so genuinely entertaining? Well done, Mr Rendle!
Check out the Niklaus Wirth talks
Inform 7 is a "natural language programming language" designed for writing text adventure games. It was intended to be easy for people who are primarily writers and not programmers, and I quite like it despite being more of a programmer than a writer. Nevertheless, it has some very weird features:
Identifiers may contain whitespace. It's ok to refer to a variable by just part of its name, but you do risk confusing the compiler and referring to some other variable that shares part of its name.
To declare a variable, you give its name, its type (which is called a kind in Inform 7), and then you have to declare that it varies. If you don't declare that it varies, then you've just instantiated an object (which is called a thing in Inform 7) instead.
A gadget is a kind of thing. [this is a type declaration specifying inheritance]
The really keen blender is a gadget. [this creates an object]
The nifty garlic press is a gadget.
The rustic mortar and pestle is a gadget. [this may cause problems for the compiler because the name contains the word "and"... but maybe it won't, who knows?]
Jenny's favorite appliance is a device that varies. [this may cause problems if there's also a thing called Jenny... but maybe it won't, who knows?]
If you want to write a function called "it's raining" that returns a boolean, you say:
To decide whether or not it's raining:
"unless" is a keyword in Inform 7.
If you want to write a function called "flush the toilet" that doesn't return a value, you say:
To flush the toilet:
If you want to write a function called "the favorite appliance of" that takes a person as an argument returns a gadget, you say:
To decide which gadget is the favorite appliance of (the subject - a person):
There's way more, but I can't even remember how it works right now...
And I thought java was verbose
I love it already
I feel like I'm in a weird limbo between Stanley Parable and Stephen Fry when watching this content. Some of the most absurd concepts delivered with a dry English comment made me laugh harder than I ever thought I would at programming! Thank you for a great presentation!
Aw man, I was waiting for Perl's contexts. You know, when operators such as ASSIGNMENT mean different things depending on context, which is implicit and inferred.
This is the best comment section I've seen in years!
I thought of something perfect to add. TCL has this feature called "upvar" that lets a function access the scope of the function that called it. It can take a number parameter to access higher levels of the call stack.
what's upvar
@@Vikezor Nothing much, what about you? :D
@@user-ym2mp4jh2c aaaa e
Internet won.
Is that similar to a "thunk" in Algol 60?
I think Lua metatables could be integrated by adding a massive amount of overhead to each memory access, and of course these should be mandatory for some obscure datatype, and extremely difficult for the programmer to implement correctly.
Since it would be so special and would generate a much larger compiled file if it is used, why not show it's significance with, idk,
BS_Set_META(€a,€b); and of course, since the function was broken in the first release, we need to include the fixed function as well with every release: Set_META_real(€a,€b); (!note: this one not prefixed with "BS" in order to comply with 69% requirement)
I recently learned Python and I like it quite a bit. It is actually very much like Lisp, the language I’ve used the most in the past. But the concept that spaces are part of the language is something I thought was brain-dead when I first learned the language and something I still think is brain-dead. Of course, with a decent IDE, it’s easy to keep track of, but a decent IDE also makes it completely superfluous because a decent IDE can autoformat your code anyway. I still prefer parentheses or some other characters to mark beginning and end of a code block. It’s completely unambiguous and requires less effort than typing five spaces.
What kind of moron actually types 5 spaces to get a tab indent? There is a lot wrong with that.
Typing five spaces sounds like a nightmare. You should try four spaces instead, pretty sure that's the standard :D
I agree 100%. Some time ago I needed to update a Python code without any previous contact with the language (I had worked with things like Fortran and especially C/C++ for decades). The job was quite easy but I remember that I needed to call my son-in-law (a developer) and ask him: "Is it real? Do they actually use whitespace as part of the Python language?".
My first computer job was translating 1960's APL code from printouts and program outputs to applesoft Basic. I was 18 and had no idea about APL, but I BS'd my way into the job and they gave me a 5ft high stack of printouts and a APL textbook from the 1960's. That paid for my first 2 years of college.
I think you should add "template" before every function to make sure that compiler errors are completely undecipherable. Also, if you fail to put "template" before your function you should get a fatal warning from the compiler. Just that. "Fatal warning.". For every function definition.
However, we are not that sadistic. You can of course turn of these irritating warnings with a compiler option. Which will implicitly put a "template" line before every function, and these extra lines are counted by the compiler so that all your compiler errors now refer to line numbers which are off by an extra line for every function in the file.
And if you really want to win over the C++ crowd (in addition to the COBOL warriors), a BS program MUST be completely constexpr.
I think 'missing constant' would be a worse error message.
Reason behind name:
missing 'template'
=> missing nothing (no template types)
=> missing null
=> missing constant (since null is a constant)
Ok, but making the language strictly useless seems excessive. If everything is `constexpr`, you can't do IO... unless your notion of `constexpr` is borked, which could be a "good" feature.
@@MCLooyverse the language has functions, it should be enough for IO with constexpr
@@Expllosaoriginal No, you can't have a constexpr side-effecting function. Those are antithetical.
The problem with forcing everything to be constexpr is that you would then know what's going on. You know that your output binary will always return a single value and close, so deciphering the code is about figuring out what the value is.
constexpr generally makes code simpler, since it explicitly PREVENTS you from writing code with some clearly defined properties (being determinable at compile time). A bad language is one that lets you do lots of horrible things, but prevents you from doing seemingly normal things with no rhyme or reason.
Brilliant talk... No NUL moments!
Just yesterday it took me around 30 minutes to figure out why one particular basic Latin character in my jpeg code registered as 2 bytes when I highlighted it. It should only have registered as 1 byte, Until figured out that the character was paired with a non-breaking space character (Alt0655), being of course completely invisible. There are definite time-saving advantages switching from ANSI to UTF-8 when working with image binary...so I gave meself a pat on the back😄
5 amazing suggestions from the audience sounds like some sort of record. Thank you for the excellent talk Mark! I was initially afraid this would just be a repeat of the old 2014 talk but no - it (being the BS language) is far worse and the talk is far better and more refined!
Thank you!
Time-stamped summary of languages and a few key points in the video.
1:23 - COBOL; Excessive Boilerplate
2:22 - IBM COBOL; Extra Excessive Boilerplate
2:55 - APL; Sane "Hello, World"
3:27 - APL; Conway's "Game of Life", Use of Ridiculous Symbols
4:21 - INTERCAL; Parody Language, Requires Correct Ratio of Politeness, No GOTO, but Instead COME FROM
7:07 - Visual Basic; Not OOP, Basically Non-Existent Data Access Layer
7:54 - Gupta SQLWindows; Tree-View Editor, Saved to Binary, Compiled to Byte Code
11:33 - PHP; Ridiculous Name, Inconsistency, Variable Prefixing, Hassel of C/C++, Slow Performance
14:38 - Python; Significant Whitespace
17:00 - C/C++; /* Comment Syntax */
17:41 - All Languages; null, Nothing, Nil, undefined, nada, etc.
18:21 - Ruby; Unless Conditional Modifier
20:11 - Greek Question Mark vs Semicolon
21:10 - JavaScript; Senseless Equalities/Inequalities
26:48 - Visual Basic 6; Parentheses as Array Accessors
28:31 - C/C++; Macros
32:43 - Flow, TypeScript, Python (Also PHP); Gradual Typing
35:28 - Java, C, Rust; Various Memory Management Topics
39:04 - INTERCAL, BASIC, C#; GOTO
42:38 - BASIC; More Keywords
43:52 - FORTH; C#, JavaScript, etc; Evaluate
48:24 - GoLang; Date/Time Parsing Format
53:21 - MatLab; Echos Anything That Doesn't End With a Semicolon
54:24 - Visual Basic; AndAlso Short Circuiting
53:43 - If Switch Statements Require Breaks, Why Not Conditionals?
56:55 - Ruby; Optional Parentheses on Function Calls
Actually... 2:22 - speaker gets real confused and doesn't reali as that that first two, and last several, lines in his example COBOL program are JCL (job control language) which was used server side like a .bat file, to load and start the actual COBOL program, which is, for some reason embedded in it here, instead of merely referenced by it. The rest used some things li me being able to create short names for stuff like the output location, i.e. console in this case, which was added on the theory that a CNSL was several bytes shorter and thus saved huge amounts of program space. Which I suppose 'might ' sometimes matter on really old systems, with super tight memory constraints...
In any case, JCL was intended to load "any" process/program, not just stuff written in COBOL, hence my comparing it to a DOS .bat file.
Actually... 2:22 - speaker gets real confused and doesn't reali as that that first two, and last several, lines in his example COBOL program are JCL (job control language) which was used server side like a .bat file, to load and start the actual COBOL program, which is, for some reason embedded in it here, instead of merely referenced by it. The rest used some things li me being able to create short names for stuff like the output location, i.e. console in this case, which was added on the theory that a CNSL was several bytes shorter and thus saved huge amounts of program space. Which I suppose 'might ' sometimes matter on really old systems, with super tight memory constraints...
In any case, JCL was intended to load "any" process/program, not just stuff written in COBOL, hence my comparing it to a DOS .bat file.
@@patrickelliott2169 By that point i already had heard more than enough stupidity & stopped this BS video - plus it forgot Assembler
YOUR COMMENT SHOULD BE PINNED TO TOP OF PAGE.
Here are a few ideas to add:
Bash scripting uses a wide variety of character pairs to enclose conditions - parentheses, square brackets, double square brackets, etc., and what is or isn't allowed in the condition, how you write it, and, in some cases, whether you can even do the comparison changes depending on the enclosing characters. Thus, BS unless (null) would not do the same thing as unless[null] and unless [foo == bar] might be a syntax error while unless [[ foo == bar ]] or [ foo ∙eq∙ bar] might be legal. (FYI, I used a 'bullet' character around the eq, for much the same reason you used the Euro symbol.)
You discussed adding a required "break" statement for each scope. If a break is omitted, what happens? I would propose that execution simply continue with the next statement, ignoring whatever condition might or might not have been (intended to be) applied to it. Thus, if you omit the break statements in an 'unless' conditional, the code would act as if the 'unless' statement was not there.
If you were to include a switch or case statement, I would suggest again borrowing from bash - their case markers are a value followed by a single ')', which makes parenthesis matching for finding errors completely useless. You could also take the case terminating ';;' and expand it to 'break break'. At the end of a case: if there is no break statement, fall through to the next case's code, if there is only one break, continue with either the case after the next case, or the otherwise case, and if you have break break, leave the entire case statement.
I think having a 'come from' could be interesting, but it should only be allowed inside loops or conditional blocks. It might possibly be allowed inside function bodies (outside of loops or conditional blocks within the functions), but only if the source location is outside the function body, which is to say that it provides a way to jump into the middle of a function.
Of course, there is always the Cobol ALTER statement....
if test '$var1' -eq '' -a "$var2" == True ; then echo "$vElem=${vText[$vTeSu]:0:4}" ; fi # Welcome to bash, best language ever!
Some languages put a number after the break, indicating the number of levels to break, so if you have a while inside of a while, break 2 would break out of both. You then get interesting effects when a new programmer takes over and inserts a for loop between the two while's! A "goto" could be used to prevent this "bug", but we all know that goto's are bad and lead to spaghetti code. I would use break 99 to be safe -- break 99 levels. An even higher number may be needed if the program goes into bottomless recursion.
[foo == bar] failing vs [ foo == bar ] working is a nice addition, but it should just be accepted with a different meaning.... like [foo == bar] is [ foo == bar ] but in global scope
Absolutely the most hilarous hour I have spent since I was first exposed to programming languages, some 48 years ago! Thank you for the overview of this fantastic programming tool, BS!
I have found a bug in the BS specification. It seems you, inadvertently, allow multiple "and"s for a single do, meaning you could do 4 parallel threads like this:
do:
thing
and:
thing
and:
thing
and:
thing
Clearly the intended syntax is to simply nestle them, like this:
do:
do:
thing
and:
thing
and:
do:
thing
and:
thing
Which we can all agree is probably what you meant :)
Nice.
But they do different things! First starts 4 threads, second starts 2 threads that start 2 threads. Actually making the whole program fork at that moment would be even more diabolical.
It's a "feature", not a bug.
It should have been implemented as unix fork(). The program flow after fork splits into 2 threads, fork() returns zero for one thread and non-zero for the other.
So instead of do: thing and: thing onw would write:
thing;
else
thing;
unless fork() == 0;
Do not let the lovely British accent deceive you. This man is creating a monster right in front of you by combining every ugly conceivable feature you could possibly hate. He tells you he will concoct a terrifying, brilliantly horrible FrankenZombieLanguage, and he even gets the audience to help. I am suddenly applauding him for showing what kind of bastards live in this world, who will directly harm mine. He is the John Oliver of coding.
Right? This guy should be flagged as an enemy of the state!
A programmer's hell involves sitting in front of a single console running BS where the only way out of your otherwise eternal torment is writing a perfect BS compiler using BS. You don't get access to any documentation, syntax highlighting or anything. You have to work in raw text files. As a side bonus, your chair is very uncomfortable and you don't get any coffee.
I would've thought Malbolge would be the language of "choice" for programmer's hell.
Damn, that coffee part is truly inhumane.
Yes! Hell for the ones who write crappy code and don’t document, not even a comment!
And every 3 hours Satan calls you to a stand-up impaled-on-stakes meeting to discuss progress
I’ve worked on Perl coding with only notepad.exe available. I can confirm, it is hell.
The #define with regex replacement is actually pretty ingenious. It lets you create a simple ad hoc DSL within a source file. I have use cases for that, I guess.
It's even more amusing that since you put a string after a hash symbol, the youTube analyzer is following the example of Twitter, FB, Instagram, etc and created a hashtag out of it. Clicking it in your comment opens a page of videos it thinks are related to "define". lol.
One dev put the following line in all of their code:
#define is not a hashtag
It went unnoticed until somebody introduced a variable "is" .
[squirting you with a spray bottle] No! Bad.
no joke: there is actually a macro assemble that has regex-based preprocessor macros.
Yeah I said the same thing. This would be pretty great. Though I think to make it more spicy, it should apply to any subsequent #defines later on. So you can use macros to write your macros.
After 40 years of writing software I can attest that Academics and Mathematicians should never be allowed in the design of programming languages. Logo is a terrible implementation of a good intention. Current C++ is a nightmare complication of a great idea. NodeJS is under planning extended to insanity. Python is bureaucratic punishment of programmers.
My own code suggestion:
In Rockstar, you can declare a variable with a space in it (space case, if you will), so no need for snake_case or camelCase
Fortran also allows spaces in variables, though it is not significant. FOR 10 I is a valid variable..
This is such a fun talk! I could be wrong, but I believe you've introduced a memory leak in your Say function. You're not deleting the €things variable. 😉
C# also has the confusing "skip parentheses" on object initialization if you use curly braces and set some properties instead.
Well no one mentioned VB6 END statement , good luck finding that in code
You can only “skip parenthesis” on object initialization when you don’t define a constructor.
You're right, I absolutely did. On purpose, of course, to see if you were paying attention :P
Great presentation, I couldn't stop laughing. I feel old that I know about all the items he used from the languages. Option Base was what you used to set the array index in VB6. I wrote tons of VB6 code. You also had to create a '.bas' file to set globals. I do not miss that language
You didn't need Option Explicit as you could dimension the lower bound, eg DIM f(0 To 10) or Dim (1 To 10). You could make it anything, eg Dim f(-100 To 100) or Dim WWII(1939 To 1945) so you didn't need a variable to hold an offset which you always got wrong. I wished they'd kept that.
Can I just say that pluralizing a data type to indicate an array is about the most wonderful concept I've ever heard of. Bravo!
That is pretty much standard.
But what would you do if the plural clashes with the singular of another word?
We should do multidimensional stuff. Like a framebuffer with individual colors would be of type Bytesss
@@DMoberg this happens in matplotlib documentation. It has a type Axis and a type Axes
could be very powerful. And the plural of "sheep" would be "sheeps", in this case a two dimensional array (due to the collective noun).
I recently began programming an embedded system using Zephyr RTOS. Its been a while since I have setup a C build. I had to review the Make language, learn about CMake and Ninja, that build Make scripts, then learn about West to build Ninja scripts and KConfig for build configuration. On top of that, Zephyr has decided to borrow Device Tree from Linux to configure boards (because of course everyone knows about Device Tree), but to get the device tree configuration actually into the C code, drivers need YAML files as glue. The device tree files create macros that are nested many levels deep, so that whenever there is a problem, you get an error like: 'PINCTRL_STATE_DT_N_S_soc_S_pwm_40021000_PINCTRL_IDX_0_UPPER_TOKEN' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_pwm_4001c000_PINCTRL_IDX_0_UPPER_TOKEN'?
So, for BS I propose a separate language called CRAP (Configuration Reader And Prognosticator) to do build configurations, Wipe to cleanup build artifacts so they don't get checked in to the repository, and Toilet as the name of the compiler. Of course, all CRAP options are declarable on the Toilet command line, but formats are completely different. And, we need a name for the "ecosystem". How about Septic?
Wow man, I couldn't help to laugh your entire exposition, nailed it, awesome mature and common-sense perspective as well, thanks for doing this
Absolutely brilliant!
Could I suggest adding from PL/1 (coming from Fortran if memory serves): implicit typing based on the first character of the variable name (which is why for loops traditionally use a lowercase "i" as it was the first short int available)
also Fortran's implicit save. If you assign a value to a variable on the same line that you declare it, the variable is given the save-attribute. This is basically the same as a static variable, so it will not be reinitialized on the next function call.
Sounds reasonable.
From TeX: There’s a special “expandafter” macro that causes the macro engine to temporarily skip the next token. If you want to skip more than one token, you have to use additional expandafters (since expandafter is a macro, you can apply it to itself).
And if you want to do the action n times, you have to use 2^n-1 copies of the token in your code.
One more beautiful code design suggestion adopted from Arduino:
instead of a=b you put assignValue(a, b->value()), and moreover, the HelloWorld project should include a builtin initialized 4GB of memory for buffers and predefined one-letter variables.
Arduino is just C++, it doesn't have assignValue(). MatLab does though.
I love this video. I have some suggestions:
Using infix notation in BS is too much polite I think. The postfix notation is just for BS!
So, the "unless €i < 1 break;" should be written as "unless €i 1 < break;"
Also, using '' signs is too much readable, the bash "lt" and "gt" is more appropriate, so the "unless €i < 1 break;" will be written as "unless €i 1 lt break;"
I came to the comments to look for the 'no infix' suggestion :D
lt/gt is good, but too easy to type, I suggest < and >.
Or yoda style: Break unless less than is 1 it
Polish notation lovers? Great great!
RPL for any mathematical expression, infix for string manipulation and prefix for array manipulation.
Postfix notation (RPN) is too familiar to users of graphing calculators and happens to be the natural sentence order for several human languages, including Japanese, Latin, Turkish, some constructs in Romance languages, and so on. Make it prefix notation instead, after all, you have to know what operation to apply things to before knowing those things, right?
+ - 20 * 3 4 1 = 9
Thank you Mark for these germs of inspiration. Despite a well structured and rich language we got ourselves already, here are a few improvement suggestions.
- is for instanceof, and null is everything, and is a type as well (thank you typescript) whose only instance is null itself
- Just like Java generics, add erasure at compile time - as feature, please
- Just like the JDK, be backward compatible no matter how modern the world become
- Just like Java compiler, compile nested classes as first citizen files
- Java is so awful it could well just be SP. When litterals are passed as parameters, optional type, if specified, must be the wrapper type instead
- Please, stop listening to the community. Just follow Microsoft lead, because you know better (starting with my suggestions here)
- Make your package manager use a different language and stack, like groovy and gradle in Java, or cargo for Rust
- The compiler to follow Rust and optimize everything recursively... And if there's ambiguity, interactively ask the developer to pick from some variants
- Talking of PHP/Wordpress or Ruby/OnRails... Well, make a frameworks which design imperative determines which feature gets into BS
- I already love this one. Programmed obsolescence of keywords. That !important to sustain the hype around BS and get people to forcefully upgrade to latest features
- SQL got `DESCRIBE TABLE` but Postgres? Well, some keywords can start with backslash
- That no-parens function call should not be for zero-arguments but 7-args functions call. Just that
- From JavaScript, assigning a method to a variable disconnects the this context - pure evil
- Like Redis, you can make BS scriptable (you did EVALUATE) but those scripts should be in LUA (a different programming language, or SP v.2.1.3 specifically, yes)
- Make a special engine to run BS and then, make it paid by companies with +50 employees ^^
- If anyone ever make something successful despite all eveil in BS... Please sue them to get your share.
"Business people can't even describe the applications they want, much less write them." This made my day - this statement in the opening section alone made watching the whole 1h video worthwhile.
This is one of the best conferences I've ever sat through. I do not regret watching this in the slightest.
The original "goto considered harmful" paper was, in addition to other things, asking people to stop jumping between methods with their gotos.
The problem is that many people took it as a blanket no. For certain types of code, such as error handling or nested loops, using goto can make your code cleaner and more efficient. Nearly all things in life should be done in moderation. /* There are exceptions, of course. Like always comment your code, but not every line. */
@@anon_y_mousse
Ironically, COBOL has the more elegant and more structural "continue" (and "next sentence") statement replacing the more unstructured and more error prone "go to" statement within iterations.
COBOL also has a more structural "evaluate" statement solving multiple elseifs with multiple complex condition statements.
Unknow for those who never coded COBOL, it has been the stable and reliable backbone language of the financial world. It might still be, I don't know, I haven't programmed COBOL for over 20 years.
p.s. I also used to be a Java programmer.
@@wimahlers Interesting, although C does have the continue keyword as well. It's just not enough in certain circumstances. Like if you want to break out of an inner loop and you haven't yet met the condition of the loop, and you can't modify what it's testing to do so.
@@anon_y_mousse
In COBOL there are keywords for that as well. Namely:
"next" to exit all nested loops.
"exit perform" to break out an inline perform loop.
As always, use all code statements, especially statements breaking the flow of processing, in a sensible way.
I always stay clear of GOTO for two reasons. First, I always assume I'm leaving behind a mess; and second, it seems a bit rude. The second on also applies to returning early from inside a loop.
That IBM COBOL example is bollocks - it's a COBOL routine embedded in JCL (Job Control Language). He's put two things together and sniggered at the result - "I don't even understand what it's doing" - well, that's bloody obvious. At that point I gave up on this twaddle.
Very funny!
For GC, I would like to use ”retain” for variables. Every fifth line, or so (maybe like PLEASE, not too much, not too little), you have to declare which variables you still want to be able to use. Other variables will be taken care of by the garbage collector. As an added bonus, this will also bog down the compiler.
Perfect. You can't effectively have more than five variables in scope because you'll have to constantly retain them in sequence. But it's good practice to circumvent this by putting your stuff into a null-type array that can hold whatever. But as the type is lost you have to keep track of memory bounds in another array.
@@black-snow Another idea is to store the five variables in registers (per scope), which is dynamically named when compiled.
rust
they won't be taken care of by the garbage collector, instead the garbage collector will recognise that something *should* be deleted, and if it's used before it's deleted from that point forwards the function will complete, and when it reaches the return keyword it will put out a runtime error saying the infinitely helpful "variable used before deletion" with the stack trace targeted one line after the place where the function was called.
additionally, the compiler will use a utterly random mathematical function (using the hash of your application source code (any and all files in the directory you run the compiler, as well as subdirectories recursively) as the random seed) to determine exactly which lines are required to have a retain. Changing your source code to fix the issue (it doesn't tell you which line should have a retain) will change which lines are supposed to have a retain.
For this to still be practical and to have a chance of compiling, it should have an average probability of 1 in 5 (*average*, maximum and minimum are left to implementation) and give flexibility of +/- 1 line from the line it picks.
@@justsomecommentchannel8602 That's not how Rust works.
To be extra evil, you could take a page from HDLs like VHDL and Verilog, where everything is concurrent unless explicitly noted, and have blocking and non-blocking assignment statements.
Yes, for their intended purpose, these features make perfect sense. Not so much in an ordinary programming language
No, no, don't even suggest it! Verilog already has a fuckton of race conditions because of that (testbenches, mostly)! Just save them the trouble and turn half the language into stuff that can't be synthesized, and yes, we'll call compilation synthesis because fuck you, that's why.
My teacher was a developer of verilog (not a developer who uses verilog, he developed the verilog itself) even he said that verilog was a mess to use.
Or it should be like make and have a separate use of equals that assigns an expression tree instead of a value to a variable. Not quite a function, but almost.
VHDL! A good feature to take from there would be the BEGIN / END pairing, along with the requirement that some blocks end with “END [block type]” but other blocks end with “END [block type] [name]”.
@@PaulFisher To take it a step further, some blocks would end with just "END" and some would end with the type of block written backwards. You can thank bash for that idea, only it'd be like while ... elihw or unless ... sselnu;
I once got a Java codebase that used throw & catch to pass messages between different parts of the programm. It was never run for very long, but once we did, we eventually got an exception queue out of bound exception, which is not catchable, since the exception queue is already full. To fix that issue, you just have to rewrite the entire structure of the programm your working on to not do that, so that was a fun project. I was meant to just add IPv6 support (yes they were doing network testing with Java, don't ask).
Another idea from html, if you have a old school table and you put any tag between the table and the cell it moves the code outside on top of the table.
Maybe the compiler can detect if you are using some code in the wrong place and moves it to the top of the function for you.
The compiler should do that for _all_ syntax errors. Move the code by a random number of lines (backward or forward), randomly adjusting indentation as required, until it succeeds at compiling the code. To ensure is always succeeds at compiling, a bug in the indentation-repair logic sporadically converts code into comments and vice versa.
@@BrendonGreenNZL Best part is that way you won't get an error log about meaningful things, but you can still claim (and prove) that your compiler does in fact have error handling. You can thus make very elaborate and fancy error handling. In the safe knowledge that your compilor will do whatever it can to compile succesfully, and thus never actually give an error.
You touch on an important point here, in order to target a wide variety of output file generation (for producing HTML pages for example) BS should support some form of in-line templating where you can mix BS and plain text.
@@dave7038 and let the programmer include page numbers like '1 of 16' right aligned with spaces manually but checked at compile time
Reminds me of that one JS framework that fixes your typos in variables
C++ has, depending how you count, up to seven methods of variable initialisation. So I suggest that BS is having also a variety of methods. Additionally, because we strive for a more diverse society, BS should have quotas for each of the method so that no one method is used excessive more than the others.
Yes, we should encourage copy pasting instead to bury ourselves in! Brilliant idea! 👏🏻
Unfortunately for your diversity, kindof the point of this talk is to take things that already exist, possibly with some tweaks. I don't know if a language that keeps track of how many times a function is called, and cares about it.
@@MasterHigure yes, you are right. It is off topic
This is an actually funny diversity policy joke
In high school, we used RPGII. In this, you needed to make sure you reference the type of line that was programmed in the specified column. I think it was column 6. These were H (Header), F(File), I(Input), E(Exception), C(Calculation), O(Output).
Because this was used on the IBM System 34, we needed to reference where the character started and its length.
Each item still needed to be in their proper columns as well, since this was designed to be used with punch cards.
Including some of these features in BS would be nice. To convey further annoyance, add contractions like shouldn't. Require long statements to have furthermore, which must be referenced using a combination of superscripts and subscripts.
Since the language is pass by value, you can make it so that the objects are only shallow copied and you have to by hand deep copy the object in every method to make it work because without it, delete would also delete passed value and the return value of the method since its only shallow copied.
Another freakish one, even if a bit arbitrary:
Word usually only has simple statements using logical formulars and strings, but can handle nested code by passing it as a string parameter. Though to identify this, the code needs to be capsulated in curly brackets. It aren't your normal curly brackets though, you need to press Ctrl+F9 and it will create a "this is code" marker in the background that you can not copy paste and looks identical to a pair of bold curly brackets. Which will for eternity not only disrupt any attempt to use stack overflow for these formulars, but also force every developer to explain this behaviour in every comment they make if they want to help people online.
I LOL'd at the € symbol reference, because there's no # key on an Apple keyboard - same vibes.
I like “unless” for inverted “if” statements. It's useful for checking that inputs to a function are valid; often, the check for that an input is valid is simpler than a check for that it's invalid. So, such function would have a check for that the inputs are valid, and then the rest of the code would be with that assumption.
I agree, it is an interesting alternative when you would otherwise negate the contents of "if". Not a great one if the language forces you to use it somewhere. For example Pascal had its cycles quite weird with `while` and `repeat-until` as options.
I think that if BS gets any real cycles, they should definitely use `until` rather than `while` :D
"Business people can't describe the applications they want, much less write them" Yup. I laughed at that.
This is universal in anyone trying to translate from one profession to another. For years, I translated between embedded HW and SW groups. The schism was unexpected. Someone has to bring up the first silicon board…with what? Basic understanding on both sides should be required training. SW folks always had to fix HW screw ups and were always expected to make up for time lost by slow HW. Unfair, and I was always defending the SW release slippage.
LOL - spot on. It was like pulling teeth to get someone to describe what they actually wanted.
Typical meeting with requestor: Do you need sub-totals? uh - yes I guess so. How about totals? Uh - yes that too. Page breaks on Division changes? Oh yes - gotta have those. Sort order? uh - what do you think? Me? It's not my report. Uh, well, I'm not sure that I understand Sort Order. Exactly what do you mean by that? I tell you what I'll do. I'll just design this report that I think you might possibly want, and then we can just keep changing it until it makes sense to you. GREAT!! You da' man. I'll call you when it's ready. Bye.
Actually they can describe them. They just can't write them up.
You know, if I were designing a language, I would want to make sure the programmer knew what they're doing, so I would require every translation unit to have a declaration that the programmer knows what they are doing. As duplicating that string would suggest the programmer is simply copying and pasting solutions they found on stackoverflow, each declaration of correctness should be distinct at both compile and link time. Runtime checks should ensure those statements of correctness exist by verifying them against a correctness revocation list. Additionally, every compilation of the translation unit should revoke the previous declaration and require a new declaration to be made. To make sure the programmer doesn't lie, this will require a code signing certificate and they will have to register with the Program Correctness Registry and pay a small annual fee.
Here’s a couple features from TI-Basic that I enjoy (the language of the Texas Instrument graphing calculators):
1) Variable assignment is right handed (value -> var)
2) You need opening parentheses (for anything), but closing parentheses are optional if at the end of a line (I believe in certain contexts too, like a list would be { 1, 2, 3 -> L1)
TI-Basic also has 1 indexed lists, which makes it even better
I think the thing that would make this aggravating beyond anything is just to break as many conventions as possible. For example the white spacing is just so common that the was BS breaks it makes it aggravating. Any convention that would make switching languages easier should be ignored and go in the other direction.
Also CoffeeScript actually has some features that are syntactic sugar (which includes unless), but also allows for really lazy programming habits. When I’ve written in CoffeeScript, I generally utilized those shortcuts and it makes code so much harder to read
I’ve worked with a _lot_ of Perl (enough Perl that I’ve seen good Perl). And it had `unless` keyword as well. I generally liked how you could make a piece of code clearer sometimes by choosing one option over the other, but at that point, it becomes as much of a craft as writing good prose for documentation. It really stuck with me that “with great power, comes great responsibility” because like… yeah, it was powerful, but you had to use it sparingly, and only where it made things more clear rather than less clear.
Now, I program mostly in Go, and I much prefer the cookie-cutter one-way-to-do-things attitude. Doing similar things always looks similar, which is desirable in a programming language. We don’t need suspense, narrative flourish, and twists in our programming languages, like we prefer in our prose.
Didn't need closing quotation marks, either. Just imagine the trillions of precious, precious finite bytes being wasted on such luxury.
@@puellanivis Perl's TIMTOWTDI sounds like a nice idea, but in practice most shops surely had coding guidelines that boiled down to something resembling Python's "There should one - and preferably only one - obvious way to do it." Because "readability counts" ;-)
@ indeed. “use strict“ was in particular a requirement at the position I was in, and that was kind of just the tip of the iceberg.
On the topic of breaking conventions: swap the meanings of '=' and '==' (but only in conditionals).
I thought this video would be 15 seconds long. Someone comes up on stage, yells "Java", gets his applause and leaves. Glad there was a bit more depth :P
No they should go up there and yell "python" lmao
Needs more checked exceptions
I think APL and Forth are far worse than Java. Both of those programming languages were kind of eccentric.
VBA programmer for Access here and proud of it :D (it pays the bills nicely) Though I do enjoy learning other languages. I'm surprised at some of the dumb conventions in all languages though.
That said, I love being a heavy Access dev because I have control over the database design (harder than most people think), UI/UX, and code, all in one platform.
I also learned APL in college in thr 1970s. It was what now might be called a cult language. There was a group of us who where dedicated to writing an actually useful program in a single line of APL.
God, APL. I swear, whoever came up with it must have been high on shrooms when they came up with it.
@@gamerk316 as I understand it, it was originally meant to be a mathematical notation, not an actual computer language. One plus of learning it, for me, was it made learning SQL simple.
APL’s advancement was arrays. There wasn’t such in COBOL, ALGOL, COMPATIBLE ALGOL, EXTENDED ALGOL, etc. IBM Scientific Center in Houston, late 1960’s was big on this.
@@gamerk316 --- I used APL on a mainframe, the "IBM 370/148". Most programmers did not know that the IBM machine code (that you coded in Assembly Language) was interpreted (see: EVALUATE in this talk) by "microcode" -- much like processing byte-code that a Java compiler had generated. Some gifted (twisted?) IBM programmer took one of the 256 possible machine-codes, and wrote a pile of "microcode" to produce an APL interpreter that ran as part of the microcode. That "Model 148" mainframe ran APL code faster than the generally-much-faster "Model 158" mainframe, because that APL microcode worked only on the "Model 148". APL was interesting, because it forced you to think about manipulating arrays and matrices, rather than operating on scalar elements. Great, if you could transfer your acquired knowledge to programming of "vector processors" that the Oil Industry needed, to process all their seismic data within a finite number of hours.
my fav feature: start parsing and interpreting the script, somewhere along the way hit some flag which changes how subsequent lines should be parsed
btw brackets on function calls in ruby are not optional only in case you're not passing any params, they're *always* optional, and not only that but squiggly brackets around hash literals are optional (and not only that, functions do not support keyword parameters), so eg. "foo 1, 2, 3, a: b, c: d" is actually "syntactic sugar" (more like syntactic acid) for "foo(1, 2, 3, {a: b, c: d})"
Could we get support for trigraphs as well? Allowing developers to write ??= or ??/ instead of # or \ would help with international adoption.
I have resisted learning to code since the early 80s, when smarter friends than I got into it and now have big houses. But I can appreciate what he's doing and am laughing out loud at computer programming.
@@BennyDACHO But he needed to be smart and learning to code.
Make it so that programs may (later versions have) rewite Runtime/Compile loop as a part of program. Some languages are extremely flexible (Lisp, Forth .. ) and can do plenty neat things. I was kinds surprised not to hear much of Lisp or it's variants. Those can make life interesting like making self modifying high level code.
This video should be used in job interviews when you're looking for a software developer. The more the candidate laughs, the more he knows how to code properly...
Frankly, it is not funny.
It is just true.
An assembly programmer would not understand any of this. The fact that his code ask to Delete local variable is proof that he does not understand how things actually works underneath. local variables are on the stack they don't get deleted, just ignored and overriden eventually. When you sp = bp (stack pointer = base_pointer) nobody cares it is a stack.
Any suitable candidate should be able to recommend at least one element to add to BS to improve it in line witb its stated opjectives
@@MarquisDeSang Perhaps the requirement to Delete local variables is a security feature, it overwrites the data just in case you stored anything sensitive there.
@@dave7038 Yea a random sequence of numbers written on the paramaters of the stack multiple times to wash sensitive "counters values" before exiting. Brilliant. lol