Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
sarehu
Apr 20, 2007

(call/cc call/cc)

Look Around You posted:

I'm pretty sure he's not saying the criticism itself is abusive, but rather the manner in which it's delivered is. There's way more professional and tactful ways to express disagreement/misunderstanding than literally saying "WHAT? \n NONE OF WHAT YOU SAY MAKES ANY SENSE." and other very vitriolic poo poo ("you should be retroactively aborted", etc). Talking to someone that way (esp. in a semiprofessional environment) honestly is abusive.
You have to be emotionally retarded to interpret that retroactive abortion comment as vitriolic.* When I read comments like that I think, yes, I have felt that way and written like that, and I know how he feels, and it doesn't turn me off at all. So I think if other people are turned off then they are wrong to be so and their reasons or mere feelings are invalid. Also you are overlooking all the benefits of the tone he has. You'll see that sort of thing at other check-your-ego-at-the-door type environments.

*For example you'd have to be emotionally retarded to view that sentence as vitriolic too. And I mean materially vitriolic, with actual vitriol behind it.

Adbot
ADBOT LOVES YOU

sarehu
Apr 20, 2007

(call/cc call/cc)

Look Around You posted:

Also in what loving world do you live in where repeatedly posting/sending death threats to "express disagreement" to someone online is not abusive? Or having multiple people do it? How about posting their address and threatening to rape and murder them? How is any of that not abusive? Like do you honestly think that the #gamergate bullshit is actually about "ethics in video game journalism" and not a way to further disempower and subjugate women to push them further away from their sacred loving video games or whatever the gently caress their goal is now?

Like I honestly want to know how any of that poo poo is not abusive. Please justify it to me, I'd love to hear an explanation.

e: (that is not directly related to the linus style stuff, but to explain my reasoning, judging by how you framed your post talking about essentially fake abuse online, it definitely leads me to believe that you view that poo poo in the same way)

e2: ((and along the lines of the linus stuff, in what world is it not abusive to talk to someone like that? It's like the very definition of abusive language))

What.

ryde
Sep 9, 2011

God I love young girls
When I said "... and then a bunch of people rush in to defend his use of acerbic language..." I didn't expect to actually that happen in this thread. Thanks for the demonstration of the terrible cult of personality around Linus.

Hiowf
Jun 28, 2013

We don't do .DOC in my cave.
TIL the link between strict aliasing and gamergate.

Dicky B
Mar 23, 2004

Post more spurious anecdotes about linus being both abusive and wrong

ErIog
Jul 11, 2001

:nsacloud:
We all know Linus Torvalds has unparalleled communication skills that should be emulated by all. Second only to RMS, really. Any differing opinion is just trolling.

https://www.youtube.com/watch?v=I25UeVXrEHQ

Hiowf
Jun 28, 2013

We don't do .DOC in my cave.

Suspicious Dish posted:

My former coworker was Jerome Glisse, not Rik. He's going to continue working on HMM, but he expressed frustration when trying to convey his ideas to Linus. He's not overly abusive in that thread, no, but he was wrong.

He's more abusive here: https://lkml.org/lkml/2014/11/10/649

To be honest that just looks like a stern discussion to me, not abuse. The whole thing boils down to "I don't like how this looks and I don't understand why it's needed. Am I missing something?"

It's also not personal (unlike that thing directed at the gcc devs), the side-jab at *someone else* who Linus has worked with for years notwithstanding.

quote:

Make sure to read the followup where he admits he hasn't read the actual patches or actually tried to understand the problem space at all while Jerome tries to carefully explain to him the problems he faces using the simple solutions he suggested.

You're referring to https://lkml.org/lkml/2014/11/10/724
"But maybe I'm misreading it and it actually has good reasons for it"

quote:

In one of those revisions, Linus said "wait, you're doing it way X? What the gently caress is wrong with this idiot? Do it way Y instead!" and then in a follow-up, "jesus, wow, I think I liked way X instead". I can't point to the specific ML posts, since this was just in person talking on the T back home, and also a year ago.

Again, not clear how this is abusive. If you're landing something that's complicated and non-obvious then you should expect the maintainer to grill you why the more obvious solutions weren't acceptable, especially if it's not clear from the code/documentation/commit messages...and no, expecting them to read up on all past discussion that lead to it just doesn't scale. The grilling is filter to see if the person who made the odd-looking decisions has done their homework/isn't doing a quick hack, and if it's clear they aren't, the code can go through without the maintainer necessarily completely understanding it in detail. If anyone has solutions for this I'm all ears since I've been on both sides there in code reviews.

I can see where the frustration comes from, though. Such discussions are always difficult and often frustrating, people being jerks is the last thing you need to add to the mix. And it's definitely par for course on lkml, from the same thread: https://lkml.org/lkml/2014/11/11/861

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.
It's fairly mindboggling to see that people ITT need clarification as to why some may consider Linus' reactions abusive.

Hiowf
Jun 28, 2013

We don't do .DOC in my cave.

Sagacity posted:

It's fairly mindboggling to see that people ITT need clarification as to why some may consider Linus' reactions abusive.

Given that between the quotes there's quite a bit of variation in tone, that's a pretty vague complaint.

Meat Beat Agent
Aug 5, 2007

felonious assault with a sproinging boner
if not "abusive" can we at least agree on "grossly unprofessional"

MrMoo
Sep 14, 2000

daft punk railroad posted:

if not "abusive" can we at least agree on "grossly unprofessional"

This has been commented on many times, the strong language has proved productive in the LKML in order to make progress. Being overly courteous leads to significant delays, wasted time and misunderstanding between parties not only due to cultural differences. There are a lot of patches pushed by extremely arrogant individuals who have not responded to feedback and requests. In a corporate environment you would discuss with their manager or similar, in the real world you don't have such avenues. I'm interested in what other options are available? I guess you could go the nefarious route and simply block all the non-responsive contributors, but that is clearly worse.

I was watching the release management video someone posted yesterday, Facebook's solution was an internal blacklist against bad contributors. Everyone who messed up got more and more anti-points and beyond a certain point all their contributions are blocked. Not very social, as was raised by one viewer in the video, managers eager to get access to the list for consequences.

MrMoo fucked around with this message at 16:19 on Jan 29, 2015

IT BEGINS
Jan 15, 2009

I don't know how to make analogies

MrMoo posted:

This has been commented on many times, the strong language has proved productive in the LKML in order to make progress.

I think there's a reasonable middle ground between overly courteous and 'you should be retroactively aborted', but that's just me I guess? :shrug:

IT BEGINS fucked around with this message at 16:23 on Jan 29, 2015

Hiowf
Jun 28, 2013

We don't do .DOC in my cave.

MrMoo posted:

I guess you could go the nefarious route and simply block all the non-responsive contributors, but that is clearly worse.

It's somewhat obvious that the other extreme to lkml is just passive-aggressively dropping all the patches you don't like silently on the floor.

MrMoo
Sep 14, 2000

IT BEGINS posted:

I think there's a reasonable middle ground between overly courteous and 'you should be retroactively aborted', but that's just me I guess? :shrug:

I think he has apologised, or noted previous err many times for these:

Linus posted:

From a technical standpoint, no single decision has ever been that important. Everything can be fixed.... The problems tend to be around alienating users or developers and I'm pretty good at that. I use strong language. But again there's not a single instance I'd like to fix. There's a metric s---load of those.

http://readwrite.com/2014/10/16/linux-linus-torvalds-community-mistakes-toxic-environment

Soricidus
Oct 21, 2010
freedom-hating statist shill
Coding horrors: posting that makes you laugh (or cry)

Hiowf
Jun 28, 2013

We don't do .DOC in my cave.

Soricidus posted:

Coder horrors: posting that makes you laugh (or cry)

Fixed.

Pie Colony
Dec 8, 2006
I AM SUCH A FUCKUP THAT I CAN'T EVEN POST IN AN E/N THREAD I STARTED

sarehu posted:

You have to be emotionally retarded to interpret that retroactive abortion comment as vitriolic.* When I read comments like that I think, yes, I have felt that way and written like that, and I know how he feels, and it doesn't turn me off at all. So I think if other people are turned off then they are wrong to be so and their reasons or mere feelings are invalid. Also you are overlooking all the benefits of the tone he has. You'll see that sort of thing at other check-your-ego-at-the-door type environments.

*For example you'd have to be emotionally retarded to view that sentence as vitriolic too. And I mean materially vitriolic, with actual vitriol behind it.

You seem really autistic

Look Around You
Jan 19, 2009

sarehu posted:

You have to be emotionally retarded to interpret that retroactive abortion comment as vitriolic.* When I read comments like that I think, yes, I have felt that way and written like that, and I know how he feels, and it doesn't turn me off at all. So I think if other people are turned off then they are wrong to be so and their reasons or mere feelings are invalid. Also you are overlooking all the benefits of the tone he has. You'll see that sort of thing at other check-your-ego-at-the-door type environments.

*For example you'd have to be emotionally retarded to view that sentence as vitriolic too. And I mean materially vitriolic, with actual vitriol behind it.



Ok so let me reframe. You seem to be saying that since it's written online, it cannot be abusive. If you went up to someone in real life (either someone you were working with or someone you disagree with) and said those exact same things (anywhere from "you deserve to be retroactively aborted" to the more direct "you deserve to die" and "maybe someone should rape you" etc) in real life, it would 100% be considered at best extremely in appropriate, and most likely as verbal abuse (and potentially illegal!). I guess I'm failing to see how the medium in which the threats/comments are made is a deciding factor in whether the language is abusive or not. I mean, yeah it's "just words on a screen" or whatever people want to say, but in the end a real life person is reading it and (typically) a real life person wrote it, and the person on the receiving end definitely knows this and it usually (and that's conservative)will affect them similar to non-online interactions. Your defense of Linus' speech is almost word for word the kind of defense people like those in that stupid loving #gamergate poo poo use to defend themselves. Language has power beyond words spoken literally person to person in real life like you seem to think does, and just because it's (semi)anonymous in most cases, or even just disconnected through an email chain with your acutal name on it, it still affects most people to (at the very least) almost the same degree.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

NovemberMike posted:

I can't remember who it was, but there was a contributor that was basically considered the leading expert on a certain space. I can't remember if it was memory management or networking or graphics or security or what, and it's not particularly important. The important bit was that this was an old unix greybeard dude that built everything in this space originally so when he says something you listen. Linus didn't listen, he heard something he didn't understand, mixed it up with a different bug and started bitching at the guy to stop being retarded. They go into a bit of a back and forth and now the dude is building an OS for some weird architecture that was obsoleted in the 80s instead of contributing to Linux.

I don't mean to pick on you or anything, but I found it funny that this incredibly vague post was in response to someone asking for a "specific example".

ExcessBLarg!
Sep 1, 2001

Hammerite posted:

I don't mean to pick on you or anything, but I found it funny that this incredibly vague post was in response to someone asking for a "specific example".
It's pretty accurate for being uselessly vague. He's referring to Alan Cox (former tty and Linux 2.2 maintainer), and the story is on his Wikipedia page. And yes, he's working on Fusix right now, which is a Unix for 8-bit micros.

Although the Z80 isn't a particularly weird architecture, it's just old. The 6502 port is a lot more challenging.

brap
Aug 23, 2004

Grimey Drawer
I want people defending Linus in this thread to resolve disagreements with coworkers the way Linus would and let us know how it turns out for them.

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer
Hey all, let's get this thread back on the topic of horror by clearing up some misconceptions about a language that DailyWTF has everyone thinking is the worst thing ever. I know that, even though I program in it, I'm guilty of propagating the hate as well. That is why I am now posting

IN DEFENSE OF MUMPS
Side note: The commented code can be kinda hard to read without syntax highlighting. If you use notepad++, someone's made a custom language for it to highlight MUMPS code: http://npp-wiki.iwi.me/index.php?title=User_Defined_Language_Files#M

First let's talk a little bit about MUMPS (or M) syntax, and why it can kinda lend itself to horrifying code if you are a dick developer.

The first thing to know is that every MUMPS command can be abbreviated to one or two characters. This can, if you're good, lead to very compact but still readable code that doesn't take a long time to type out. If you're an rear end in a top hat, you can write nightmarish garbage.

The second thing to know is that MUMPS doesn't have an reserved words. In the same routine, X can be the name of a variable, the command eXecute, and the name of a subroutine. The MUMPS compiler (or interpreter, depending on platform), figures out which one you want based on context. It's able to do this reliably because whitespace is semantically meaningful in MUMPS. One space separates a command from its argument. Two spaces separates commands from each other. Again, this can be convenient or a tool of the devil depending on who you are as a dev.

Some basic M commands:
Set (s) - Sets a variable to a value. Usage is: s var = value

Read (r) - Reads input from the console into a variable. Can optionally display a message. Usage is: r "message to display",varToRead

Write (w) - Prints output to the console. Usage is: w !,"Hello world!" ;Note that the !
;operator represents a newline and that the semicolon begins a comment. All M comments are one line.

Do (d) - Calls another subroutine/routine, or begins a nested block of code, such as within a loop or if statement. Usage for subroutine call: d foo^BAR(arg) ;calls the foo subroutine of
;routine ^BAR and passes arg as an argument to the subroutine.

eXecute (x) - Executes a string's content as though it were code. Does not do any validation on the code contained in the string, just blindly tries to run it. It's commonly used to do things like build code based on user input. Usage: x "w ""careful with me, I can be a nightmare!""";Note that you escape quotes in an M string by doubling them up.

New (n) - Declares a new copy of a variable of the given name (and sets it to null) local to the current stack frame. M is dynamically scoped so a subroutine has access to its own locals and the locals of every stack frame beneath is except locals whose names are shadowed somewhere along the way. This one leads to some of the biggest horrors because the ability to pass arguments to a subroutine weren't part of early M specs, so subroutines had to assume certain variables. In fact, New wasn't added to the spec until the 90s. Until then you just kinda started using whatever variable names whenever you wanted. Some developers still think they're being super clever by using assumed variables all over the place, but usually they're actually making code that can never be updated again.

Quit (q) - It's both a BREAK statement and a Return statement. When used in the outer scope of a subroutine, it ends the subroutine and optionally returns a value. When used in a nested scope (such as in a loop), it breaks out of that iteration of the loop (but the loop keeps running). You can also use it as a pre- or post-conditional on a loop to indicate when a loop should stop running.


Some other commands: If (i), Else (e), For (f).

------------------------------------------------------
OK, now that I've introduced some basic syntax, let's look at some M code. I think this shows the strengths of the language, as I have to type very little to achieve a simple result. The following program prompts a user for a number of times to run a loop, then loops that many times, printing the current number. However, it quits at 100 iterations no matter what:

code:
;Routine name LOOPY
loop n numLoops; Declare the subroutine name, and our input variable. Many MUMPS horrors come 
;from programmer's desire to instead use a variable name like "n" for such a variable.

r !,"Please enter the number of times to loop: ",numLoops ;Note that I'm not validating the 
;input here. I'll talk about pattern matching later.

f %i=1:1:numLoops q:%i>100  d;%[char] is convention for a scratch variable. q:condition is 
;equivalent to If condition quit
. w numLoops_" "; periods delimit scopes. Instead of curly braces around a scope, you put a 
;period in front of each line of a nested scope. If there was a second scope inside of this 
;loop, its line would have two periods. _ is the concatenation operator.
q ; all subroutines end with a final quit statement unless you're trying to be clever and have 
;the subroutine fall through to the next subroutine in the routine. This is sometimes done so 
;you can assign a seperate name to any cleanup code so you can jump to it from the command 
;line in the event of a crash.
;
;
;Here's the code again with no comments, to emphasize how compact it is:
f $i-1:1:numLoops q:%i>100  d
. w numLoops_" "
q
-----------------------------------------
Now we've had a basic example of how compact you can make MUMPS code. Now let's talk about the real reason I think it's awesome. You see, MUMPS has its own built in data structure. M was created by a hospital to store a medical database. As a result, they build into the specification a model for how data is stored. All permanent data is stored in the form of b-trees known as "globals". Some documents refer to them as "sparse" b-trees because you can have subscript levels that have no values and simply point to a lower subscript level. There are no arrays in M, although if you create a b-tree with only one level with only numeric subscripts, some interpreters are smart enough to treat it as an array and give you O(1) access to indices.
If you know the subscript of a global that holds your data, access time is O(1). If you're traversing the tree to find data, the average case access time is O(log n) where N is the number of subscripts in the tree. Worst-case would be O(N) if your data was at the very last possible subscript in the sort order.

Local arrays and globals have the same structure. The only difference is that one is in memory and one is on disk. You make a global by prefixing the name of the array with a "^". For example, if I write:
s ^MYGLOBAL(1)=1
the MYGLOBAL array is now permanently stored on disk (unless I wipe it out with a Kill command). There's two additional really cool things about M arrays/globals that makes them an awesome convenience that I miss a lot when working in other languages.
1-Subscripts in an array are placed in sorted ASCII order automatically. Yes, that's right, you can sort for free in M without any special code or data structures to handle it. It just happens.
2-Because the data structure is part of the language specification, the compilers and interpreters are aware of the physical structure of the files and memory structures used and have extremely optimized functions for traversing and accessing data. Most pure data access is always O(log n) average case, and you don't have to do anything special to attain that.

Let me explain a little more of what I mean by subscripts. A subscript is kind of like an array index, except that any valid string (up to *I think* 200ish characters) can a subscript of a global. For example, take this code:
code:
s ^X("Hello")=".jpg"
s ^X("Hello","World",1)="tubgirl"

w !,^X("Hello")
w !,^X("Hello","World")
w !,^X("Hello","World",1)
And its output:
code:
.jpg

tubgirl
As you can see, the "Hello" subscript has a value, but the "World" subscript exists only to contain a pointer to its child subscript 1. Any subscript can have any number of child subscripts, and you can have any number of top-level subscripts for the global. This gives you the power to build data structures that are extremely easy to navigate and fast to access the data you want. Or you can build horrifying monstrosities because you're a bad programmer.

Now it's time to introduce two new commands that really tie together the power of M. $Order ($O) and $Query($Q). $O traverses a level of the tree, stopping at each subscript that exists. $Q traverses the entire tree, stopping at each subscript that contains data. $Q functions in a sortof depth-first fashion (e.g., it searches all the children of ^X(A) before moving on to ^X(B) and so on). $Q is extremely fast because it knows the physical structure of the global on disk and can literally walk over it without attempting to access any non-existent subscripts.

$O is useful when you have a global with a known structure and you want to look at the data at a particular level. For example, imagine a global with the following structure:
code:
^EMPLOYEES("ID","NAME")
		,"TITLE")
		,"TENURE")
		,"DEPARTMENT");This format is a convention for listing subscripts that are all 
		;children of the same subscript. In other words, each of these subscripts is a 
		;child of ID.
I can have arbitrarily many employees in my company. Here I walk the whole tree and print out only employees who work in Accounting:

code:
n curID ;Note that newed variables are initialized to null
;
f  s curID=$O(^EMPLOYEES(curID)) q:curID=""  d ;For loops can be a bit funky in M. You can 
;actually execute any command as part of a for loop. This is basically a while loop. $O 
;searches the current subscript level for the next subscript that sorts after the one you put 
;in. If you start with null, you will walk the subscript level from beginning to end. When you 
;reach the end, it returns null again, thus the quit condition.
.d:^EMPLOYEES(curID,"DEPARTMENT")="Accounting"
.. w !,^EMPLOYEES(curID,"NAME");I could have just done this in one line, but I wanted to demo nested scopes.
You can use nested $O calls if you need to loop over the children of a subscript you arrived at via a $O.

Another cool trick of globals is the ease of making indexes through inversion. For example, if I want to be able to look up employees by name, I can make a second global like this:
code:
^EMPNAMES(<NAME>)=ID
And simply look up the ID by looking at the subscript that is the name as a string literal. Then I can take the ID I get and plug it into the ^EMPLOYEES global to look up the remaining employee information.

Now let's look at $Q. I'm going to demo this one by sharing an actual use-case I employed it for recently: A cheap natural sort. As you know, most sorting schemes will sort "ab10a" before "ab1a", but humans would typically expect the opposite order. I had a use case where I needed to perform a natural sort (aka human-friendly sort) in M. $Q Does this dirt cheap.

Assume that I start with an array like the following:
code:
data(0)=<number of strings>
data(1)...data(<number of strings>) = <some string literal>
I can use code like the following to create a naturally sorted list from this array:
code:
n sorted,ref,val,idx,buffer,ln,inNum,oneNum,char
;
	f ln=1:1:data(0) d
	. s val=data(ln)
	. s buffer=""
	. s ref=$na(sorted) ;I haven't talked about $na yet. It basically just returns the string 
	;literal that represents an array and any subscripts in the call. Here it will just return 
	;"sorted", but later on I'll use it to build up a subscript-heavy reference
	. s inNum=0 ;There's no bools in M. 0=false, 1=true
	. f idx=1:1:$l(val) d ;$l(ength) returns the length of a string
	. . s char=$e(val,idx) ;$e(xtract) returns a substring. First argument is string to pull 
	;from, second arg is character to pull. If you use three args, 2 and 3 are the indices that define the range. It's kinda like VB's Mid() function.
	. . s oneNum=(char?1N); ? is the pattern matching operator. In this case, it's checking if 
	;the character we extracted is a single digit.
	. . i inNum=oneNum s buffer=buffer_char q ;if we're currently working through numeric 
	;characters, cat them together. We break to the next iteration of the loop at this point 
	;if we're handling a numeral.
	. . s inNum=oneNum;This makes sure that if we pass a numeric portion back into characters, 
	;we now start buffering characters
	. . i buffer'="" s ref=$na(@ref@(buffer));If we get here, we're either working characters 
	;or we've just finished with a numeric sequence. If there's numbers in the buffer, we 
	;build up our reference by making that number a subscript. @ is the indirection operator. 
	;@ref@(subscript) actually means "the whole path defined in the ref variable with this 
	;subscript added on. For example, if ref="^X(1,2,3)" then @ref@(4) evaluates to 
	;^X(1,2,3,4).
	. . s buffer=char 
	. s ref=$na(@ref@(buffer));Flush the buffer one more time after the loop exits.
	. s @ref="";A single at references the location pointed to by the whole string, so we're 
	;setting the path of subscripts we've built up to null string. This counts as having data 
	;so that our path will "exist" in the array.
Alright, so now we've walked over my initial unsorted list and created an array with a structure like this:
code:
sorted(<chunk of letters>,<chunk of numbers>,<chunk of letters>...)
;Example paths:
sorted("abc",1,"a")=""
sorted("abc",10,"a")=""
sorted("xyz",148,"hey",12)=""
Because M will sort intlit subscripts before stringlit subscripts, our paths (which are really just the strings we wanted to sort pieced apart into letter and number sequences) are naturally sorted.

Now we need to cat these things back together and put them into a line-structured array like we started with to preserve order. As you can imagine, this would be a huge hassle with $O since these subscripts can go arbitrarily deep. Step in $Q. $Q knows the actual structure of the global as it's stored in memory/on disk, and can walk over all of the paths of a global that have data, walking them in sorted order.

code:
	k data; We'll recycle our original array
	s ref=$na(sorted);Building up the reference as before
	f  s ref=$q(@ref) q:ref=""  d;Like $O, $Q starts at null and walks in sorted order. The 
	;difference is it returns the next path that physically exists rather than the next 
	;subscript at the current level. We have to pass in the reference with indirection to 
	;allow the query to read it properly. With the example array above, the first value 
	;returned by $ Q will be a properly-escaped version of sorted("abc",1,"a")=""
	. s val=""
	. f idx=1:1:$ql(ref) s val=val_$qs(ref,idx);$ql returns the number of subscripts in the 
	;path entered. $qs returns the subscript at the specified depth within the path. We're 
	;basically looping over the subscripts in the path and catting them together.
	. s data(0)=data(0)+1; Increase the line count of our array
	. s data(data(0))=val; Add the new string we built up at the current line
And there you have it, a cheap natural sort with $Q. For those counting, we also did it with only 20 lines of code.

There's other commands and functions that can do equally slick poo poo if you are more familiar with the language, but the use cases are less general so I won't get into those.

One final note before I conclude. I frequently miss M's string function's when I'm coding in other languages. M has a ton of built-in string handling it all works pretty intuitively. $e you saw up above, here's some others:
$l(string) returns the length of a string
$l(string,delimiter) returns the number of pieces in the string as broken up by the specified delimiter. The delimiter can be a string of any length, by the way.
$p(string,delimiter,n) returns the nth substring of string as broken up by the specified delimiter. Can also replace the piece found using an optional parameter.
$e can also be used to replace a substring. You specify the source string, the range you want to replace, and the string to replace the range with.
$f(string,substring) returns the ending position of the substring within the string. Searches for the first instance unless you specify an index to start from.
$r reverses a string
$t can replace all instances of one character in a string with another character.

$l+$p is just so useful for breaking up strings and parsing them that I go crazy whenever I have to resort to poo poo like Mid in VB or the various horrors Java inflicts for string parsing.
A final useful function is pattern-matching. The syntax is <string>?<args>. It returns 1 if the string meets the args and 0 if it doesn't. It's basically a simplified regex, but with friendlier (arguably) syntax.

Here's an example of using pattern matching to confirm that a string containing an SSN complies with SSN formatting:
code:
s ssn="123-45-6789"
s match = ssn?3N1"-"2N1"-"4N
The argument string breaks down as such:
3N = "exactly 3 numbers"
and then
1"-" = "exactly 1 hyphen"
and so on.

You can specify either string literals or certain predefined character classes.
N= number, A=upper case or lower case letters, C = ASCII control characters,L matches lower case chars, U matches upper case chars, and there's a few more.

You can specify ranges. This matches a string that is between 1 and 3 letters:
string?1.3A

This matches a string that is arbitrarily many characters (and only characters):
string?.A
If one side of the period is blank, the boundary is infinite on that side, so you can specify only a minimum or maximum count if desired.

Thought it's not quite as powerful as regex, I think it's way more human readable most of the time, which makes it easier to debug and maintain later.

To conclude, M is a pretty powerful language that can actually make a lot of common data-driven work easier. If your application's workload is heavily dependent on organizing and retrieving data, I think it's pretty pleasant to work with. It's great as a back-end database. Please use something modern for your client, however. I like working in it a lot. If you want to try it out, GT.M is a free, open-source implementation of MUMPS that anyone can download and play with for free.

This has been your "weird, misundersood language" care post of the day.

sarehu
Apr 20, 2007

(call/cc call/cc)
In "the real world" it's not abusive to make statements of the form Linus made either. That is, saying "people that read bytes one at a time deserve to be retroactively aborted" is not abusive. It's hyperbolic nonsense and meant to be taken that way. The same goes for saying somebody likes seeing their name on "acked-by" lines, in the context that it was in.

I have no idea why you're talking about people saying other people should be raped, Linus is not doing that. People that find the word abusive useful for being unspecific and non-falsifiable have begun using it to talk about Linus. And other people repeat it word by word like the good little followers they are.

Look Around You
Jan 19, 2009

sarehu posted:

In "the real world" it's not abusive to make statements of the form Linus made either. That is, saying "people that read bytes one at a time deserve to be retroactively aborted" is not abusive. It's hyperbolic nonsense and meant to be taken that way. The same goes for saying somebody likes seeing their name on "acked-by" lines, in the context that it was in.

I have no idea why you're talking about people saying other people should be raped, Linus is not doing that. People that find the word abusive useful for being unspecific and non-falsifiable have begun using it to talk about Linus. And other people repeat it word by word like the good little followers they are.

Hyperbolic or not it's extremely inappropriate to say that someone is too stupid to live when you're actually trying to work with other people. Even (especially) if you're in a supervisory role, demeaning people that you don't agree with/who are actually wrong is Very Inappropriate and extremely unconducive to continued contribution/constructive interaction.

And the reason I brought the other stuff up is because it's literally the same defense that they use. "Well I say it all the time so I wouldn't be offended if someone said it to me, so you shouldn't be offended either and you're dumb for being offended" is actually a pretty antisocial way of looking at this kind of thing. Like I don't know how anyone considers saying even the stuff Linus does appropriate for... anything really. If you did it IRL you'd probably be fired (as well you should). Doing it online on a mailing list for a project he runs doesn't make it any more appropriate than doing it in real life to one of your subordinates at work. The only difference is that he doesn't have anyone above him to tell him to knock that poo poo out for driving valuable contributors away.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



sarehu posted:

In "the real world" it's not abusive to make statements of the form Linus made either. That is, saying "people that read bytes one at a time deserve to be retroactively aborted" is not abusive. It's hyperbolic nonsense and meant to be taken that way. The same goes for saying somebody likes seeing their name on "acked-by" lines, in the context that it was in.

I have no idea why you're talking about people saying other people should be raped, Linus is not doing that. People that find the word abusive useful for being unspecific and non-falsifiable have begun using it to talk about Linus. And other people repeat it word by word like the good little followers they are.

I'm pretty sure the majority of people would find it hostile if someone said they should be retroactively aborted.

KaneTW
Dec 2, 2011

Soricidus posted:

Coding horrors: posting that should be retroactively aborted.

return0
Apr 11, 2007

sarehu posted:

You have to be emotionally retarded to interpret that retroactive abortion comment as vitriolic.

Linus says emotionally retarded things a lot. Like if someone else said what he said you'd totally be saying it was emotionally retarded. I mean, "retroactively aborted", jesus gently caress is he 14?

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

return0 posted:

Linus says emotionally retarded things a lot. Like if someone else said what he said you'd totally be saying it was emotionally retarded. I mean, "retroactively aborted", jesus gently caress is he 14?

Yeah. Some people ITT seem to think there's a distinction between "being a dick" and "being abusive". In reality, there isn't. Whether something is "abusive" might be somewhat dependent upon how the target receives it depending on your definition, but if you say something that would cause a reasonable person to think "gosh, you're kind of a dick", then you are dishing out abuse, full stop.

sarehu
Apr 20, 2007

(call/cc call/cc)

Snapchat A Titty posted:

I'm pretty sure the majority of people would find it hostile if someone said they should be retroactively aborted.

You're not responding to a post that was talking about whether something should be considered hostile. That does not mean the same thing as the word abusive.

raminasi
Jan 25, 2005

a last drink with no ice
Why do people keep saying "some people ITT" or "people defending Linus". It's just shrughes.

MutantBlue
Jun 8, 2001

Linus Torvalds is an rear end in a top hat.

Deus Rex
Mar 5, 2005

Pie Colony posted:

You seem really autistic

Abuse and name-calling: terrible when Linus does it, but great when I do it!

ryde
Sep 9, 2011

God I love young girls

Deus Rex posted:

Abuse and name-calling: terrible when Linus does it, but great when I do it!

Context matters. We are on the something awful dot com forum, where there is an expectation for verbal jabs, and few assumptions of professionalism. Linus sends his stuff to public mailing lists for serious development projects, for which there is an expectation of professionalism.

KaneTW
Dec 2, 2011

ryde posted:

Linus sends his stuff to public mailing lists for serious development projects, for which there is an expectation of professionalism.

LKML, the pinnacle of professionalism

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

LeftistMuslimObama posted:

IN DEFENSE OF MUMPS

This is a joke right

Athas
Aug 6, 2007

fuck that joker

LeftistMuslimObama posted:

Now we've had a basic example of how compact you can make MUMPS code. Now let's talk about the real reason I think it's awesome.

You are suffering from a serious case of Stockholm syndrome.

Which other languages do you have experience with? (Bragging about how a string can be "of any length" is really telling.)

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer
^You're confused. Obv a string can be of any length, what I said was that you can piece out strings based on delimiters that are of any length. This can be helpful if, for example, you want to piece out something that has a bunch of <br /> tags in it or something.

And so far I've worked in M, ancient crusty VB6, modern VB.Net, C#, Java, and C.

Avenging Dentist posted:

This is a joke right

Nope. I really think everyone who's super jaded on mumps is stuck maintaining really lovely code. Like, 90% of the MUMPS code out there is the M-equivalent of factoryfactorybeanproxyfactoryinitializer, but I genuinely think that for some applications it has inherent benefits that aren't present in other languages.

However, we both post in a certain other thread so I know exactly what code you're looking at that would cause you to disagree with me :)

Pollyanna
Mar 5, 2005

Milk's on them.


LeftistMuslimObama posted:

IN DEFENSE OF MUMPS

Pssh, MagicFS is where it's at :smugdog:

code:
@OW,
100@XV@FV
@[@{@(@IF{=0 "No more"}," bottle",IF{~=1 "s"}," of beer on the wall, ",
      @IF{=0 "no more"}," bottle",IF{~=1 "s"}," of beer"),
    @IF{=0 "Go to the store and buy some more, 99 bottles of beer on the wall.";
        @("Take one down and pass it around, ",
          -1@IF{=0 "no more"}," bottle",IF{~=1 "s"}," of beer on the wall")},
    ""}]
@MV@Av@Wb@TW
Also, MUMPS's problem is that it might be alright for back-end databases, but people still use it for this poo poo:

LeftistMuslimObama posted:

^You're confused. Obv a string can be of any length, what I said was that you can piece out strings based on delimiters that are of any length. This can be helpful if, for example, you want to piece out something that has a bunch of <br /> tags in it or something.

That's not back-end anything! That's hell on wheels!

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

Pollyanna posted:

Pssh, MagicFS is where it's at :smugdog:

code:
@OW,
100@XV@FV
@[@{@(@IF{=0 "No more"}," bottle",IF{~=1 "s"}," of beer on the wall, ",
      @IF{=0 "no more"}," bottle",IF{~=1 "s"}," of beer"),
    @IF{=0 "Go to the store and buy some more, 99 bottles of beer on the wall.";
        @("Take one down and pass it around, ",
          -1@IF{=0 "no more"}," bottle",IF{~=1 "s"}," of beer on the wall")},
    ""}]
@MV@Av@Wb@TW

I posted this before, but here's the same program in MUMPS:
code:
d n q,Q,x
      s q=+q,x=$C(115)_$C(32)_$C(81)_$C(61)_$C(43)_$C(81)_$C(43)_$C(49)_$C(44)_$C(120)_$C(61)_$C(34)_
$C(102)_$C(32)_$C(32)_$C(115)_$C(32)_$C(113)_$C(61)_$C(113)_$C(43)_$C(49)_$C(32)_$C(113)_$C(58)_
$C(40)_$C(113)_$C(62)_$C(40)_$C(57)_$C(57)_$C(45)_$C(81)_$C(41)_$C(41)_$C(32)_$C(32)_$C(115)_$C(32)_
$C(120)_$C(61)_$C(34)_$C(34)_$C(107)_$C(32)_$C(81)_$C(32)_$C(110)_$C(32)_$C(81)_$C(32)_$C(32)_$C(115)_
$C(32)_$C(120)_$C(61)_$C(34)_$C(34)_$C(34)_$C(34)_$C(115)_$C(32)_$C(81)_$C(61)_$C(43)_$C(81)_$C(32)_
$C(32)_$C(115)_$C(32)_$C(120)_$C(61)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(102)_
$C(32)_$C(32)_$C(113)_$C(58)_$C(113)_$C(61)_$C(81)_$C(32)_$C(32)_$C(119)_$C(32)_$C(36)_$C(36)_$C(81)_
$C(40)_$C(113)_$C(41)_$C(32)_$C(119)_$C(32)_$C(33)_$C(32)_$C(115)_$C(32)_$C(113)_$C(61)_$C(113)_$C(45)_
$C(39)_$C(81)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)_$C(34)
      x x x x x x x x x x
      q
Q(q) n Q
      s q=q_" "
      s Q=q_$C(98)_$C(111)_$C(116)_$C(116)_$C(108)_$C(101)_$C(115)_$C(32)_$C(111)_$C(102)_
$C(32)_$C(98)_$C(101)_$C(101)_$C(114)_$C(32)_$C(111)_$C(110)_$C(32)_$C(116)_$C(104)_
$C(101)_$C(32)_$C(119)_$C(97)_$C(108)_$C(108)_$C(44)_$C(32)_q_$C(98)_$C(111)_$C(116)_
$C(116)_$C(108)_$C(101)_$C(115)_$C(32)_$C(111)_$C(102)_$C(32)_$C(98)_$C(101)_$C(101)_
$C(114)_$C(46)_$C(32)_$C(84)_$C(97)_$C(107)_$C(101)_$C(32)_$C(111)_$C(110)_$C(101)_$C(32)
_$C(100)_$C(111)_$C(119)_$C(110)_$C(32)_$C(97)_$C(110)_$C(100)_$C(32)_$C(112)_$C(97)_
$C(115)_$C(115)_$C(32)_$C(105)_$C(116)_$C(32)_$C(97)_$C(114)_$C(111)_$C(117)_$C(110)_$C(100)_$C(44)_$C(32)_(+q-1)_$C(32)_$C(98)_$C(111)_$C(116)_$C(116)_$C(108)_$C(101)_$C(115)_$C(32)_$C(111)_
$C(102)_$C(32)_$C(98)_$C(101)_$C(101)_$C(114)_$C(32)_$C(111)_$C(110)_$C(32)_$C(116)_$C(104)_$C(101)_$C(32)_$C(119)_$C(97)_$C(108)_$C(108)_$C(46)
      q Q

Adbot
ADBOT LOVES YOU

Pollyanna
Mar 5, 2005

Milk's on them.


Come see my new web framework, SQL on Minecart. edit oh noooooooooooo

also that will break tables no matter what :(

Pollyanna fucked around with this message at 22:16 on Jan 29, 2015

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply