I think the top-10 universities do it right and the rest don't. (This is a bit of an exaggeration but you most likely know what I mean).
Most of my classmates don't usually "learn" a language. They do an assignment by copying, hammering at the computer, or just asking for help. The basis of how university is set up is antithetical to the learning and exploration of new programming languages. This is based on one simple thing that most universities do and is very easy to fix.
Don't mandate a programming language for you assignments
If this one thing was done, we'd probably instantly see a much higher failure rate and a much hire quality of turnout. If early on in the curriculum students got a tour of every one of the big name languages and got to just choose the best tool for the job for the rest of their time at university there'd be a much closer approximation to how things (at least for me) work.
If one of your projects is something like "scrape a webpage for X data" you wouldn't want to write that in a bash script (which I've been made to do [0]) I'd want to do that in Python with BS4. Or if your project is to write a parallel dot product function you wouldn't want to write that in C (which I've been made to do [1]). I'd want to write that in Julia.
Even in my class that I took for exploring programming languages we were forced to use C++. We were writing an interpreter using C++ which I'd rather have done in some Lisp-like languages.
Unfortunatly I've not been able to make the design decition to play with other language (in school) to see how they will better impact the development of these applications. I've not had to prototype stuff to see what language it will work best in (in school). These are decitions made for me.
I've found that this isn't how things work, at least for me, and I'm the one who is told "Do X" and I pick a way to do it. Whether it's by setting up a spreadsheet it a macro in it that generates the data or writing some real code. I get to choose the most elegant solution and I suffer the consequences then I didn't choose the most elegant solution since I have to my software when it breaks 2 years down the line.
There are three problems with "Don't mandate a programming language" -- I'm a lecturer and I've done it for advanced practicals in later years.
* Students expect to be able to get help when they have problems. There is a good chance no member of staff knows Julia / Moonscript / ...
* Some languages make tasks trivial -- while this is nice when you are in the real world, if I want to test student's ability to create something I don't want some students missing most of the work. How do I then mark it?
* Similarly, if the question was "implement a malloc-like memory manager", well you really have to do that in C,C++,Objective-C, maybe Rust, but it makes less sense in python.
Also, getting a "quick tour" of (say) C++ isn't really useful, students who try to pick it up by just googling are likely to write terrible code. Learning a language properly takes work.
> Students expect to be able to get help when they have problems. There is a good chance no member of staff knows Julia / Moonscript / ...
For this I have two answers. Past the first year people shouldn't be getting help with "my code won't compile". They should be able to develop the skills needed to search that on google and find SOF links.
The second answer is a question: Why don't members of staff know "Julia / Moonscript / ..." and if they don't why can't they logically reason about what's going on in the language without having used it? I don't know Go but when people have asked me to look at some Go code to see there is a bug I can still reason about what's happening. Isn't that what this article is about? All languages are just mix-matches of common idioms with new ways of expressing them. If the best of the best, those who are teaching the future generations of computer scientists, can't do this it would seems strange to me.
> Some languages make tasks trivial -- while this is nice when you are in the real world, if I want to test student's ability to create something I don't want some students missing most of the work. How do I then mark it?
If the student understands how to use the abstraction then they have likely learned something far more valuable. If you're assigning labs that consist of basic idioms that can be whisked away by common library functions then you might consider changing your curriculum to focus more on solving problems rather then codifying solutions.
> Similarly, if the question was "implement a malloc-like memory manager", well you really have to do that in C,C++,Objective-C, maybe Rust, but it makes less sense in python.
I see no reason why you'd have to write that in C/C++/Objective-C/Rust. If you're going after the idea of writing a working memory manager, and not write me a kernel that has a memory manager, then Python would work great for it. Here is an example:
class Allocation:
def __init__(self, start, size):
self.start = start
self.size = size
@property
def end():
return self.start + self.size + 1
class FirstFit:
def __init__(self, total_memory):
self.allocations = []
self.total_memory = total_memory
def alloc(self, size):
if not self.allocations:
allocation = Allocation(0, size)
else:
allocation = None
for i in range(len(self.allocations)):
current = self.allocations[i]
if i + 1 < len(self.allocations):
# Check to see if we can fit inbetween this current allocation and the next
if not self.allocations[i + 1] - current.end >= size:
continue
else:
# Check to see if we can fit inbetween this end allocation and the end of memory
if not self.total_memory - current.end >= size:
continue
# We can so allocate
allocation = Allocation(current.end, size)
if not allocation: # We can't so return NULL
return None
self.allocations.push(allocation) # Store this allocation in our memory allocation table
return allocation[0]
def free(self, start):
for i in self.allocations:
if self.allocations[i].start == start: # Find out pointer
self.allocations = self.allocations[:i] + self.allocations[i + 1:] # Slice it out
return True # We made it!
return False # We couldn't find this! PANIC!
This is crappy code but it can be done very eligently and I think this gets across the theory better then doing this in C. In this you can also experiment is far more complex datastructures easily. (What if I think of memroy as a Tree and divide the value of my node by 2 every time it's size is too big?)
> Also, getting a "quick tour" of (say) C++ isn't really useful, students who try to pick it up by just googling are likely to write terrible code. Learning a language properly takes work.
I'd say that's just because of the poor design of modern C++. You can do a quick tour of python and easily get basics, of C and easily get the basiscs, of Java and get the basics, of Common Lisp and get the basics. You don't need to master a language to see where it is applicable.
> Why don't members of staff know "Julia / Moonscript / ..." and if they don't why can't they logically reason about what's going on in the language without having used it?
If the bug is a shallow/algorithmic bug, that's reasonable. Recently I was helping someone debug some javascript code. Eventually, we found the problem was that, in javascript, that [11] < [2]. I'm not particularly knowledgeable on javascript, so I didn't know it did < comparison of arrays by string comparison. That's the kind of thing that really needs.
> If the student understands how to use the abstraction then they have likely learned something far more valuable. If you're assigning labs that consist of basic idioms that can be whisked away by common library functions then you might consider changing your curriculum to focus more on solving problems rather then codifying solutions.
This I just have to disagree with. I think it's valuable for students to learn how to implement quick sort. It's useful to learn how to implement big-integer arithmetic. It's useful to learn how you can "fake" Java-style inheritance with structs and function pointers, so you really understand what's going on under the hood.
Of course long term, you wouldn't typically implement these things yourself, but understanding the fundamentals is important.
Also, if I set a practical which involves (for example) connecting to a HTTP server, intending them to do the raw connection themselves, and they use a 3 line python program, using the standard library, have they really learnt anything at all?
There certainly is a place for giving students more freedom, particularly in later years. It's clear the modern world is moving into "slap together 50 javascript/python packages with string" type programs (and that's because it's a great way to be productive quickly), which universities don't currently teach that well. But don't throw the baby out with the bathwater!
> This I just have to disagree with. I think it's valuable for students to learn how to implement quick sort.
I'd rather the students kow how to implement large software architectures, keep line counts down, abstract problems correctly, and learn how things are done in the real world.
> It's useful to learn how to implement big-integer arithmetic
Not in my opinion. Maybe, maybe, show them how emulating FP math works but writing big-integer arithmatic functions is pretty useless for most people and is far too strait forward to require them to develop their skills of development software architectures.
> It's useful to learn how you can "fake" Java-style inheritance with structs and function pointers
You can't force them to learn patterns, you can only give them work that is better suited to using the patterns provided. You can even hint to your students "Hey you can make a get_car and get_bike and make a Drivable struct that has a Drivable->stear() and stear can be a function pointer!" Forcing them to use a pattern isn't useful.
> so you really understand what's going on under the hood
Using function pointers isn't really correct for how Java stores class/object information. This is kind of only used in virtual functions IIRC. When I've decompiled static bytecode you see stuff like LString(some function).
> Also, if I set a practical which involves (for example) connecting to a HTTP server, intending them to do the raw connection themselves, and they use a 3 line python program, using the standard library, have they really learnt anything at all?
You're assigning the wrong problem. Don't say "Make and HTTP request" say "implement an HTTP header parser". The problem is now language and abstraction agnostic and involves a much more complex problem who's complexity lays in the realm of the software organization. The HTTP Parser code can be used to read and write requests and the next lab can be to use your new library in a larger project. I think that is far more useful.
> There certainly is a place for giving students more freedom, particularly in later years. It's clear the modern world is moving into "slap together 50 javascript/python packages with string" type programs (and that's because it's a great way to be productive quickly), which universities don't currently teach that well. But don't throw the baby out with the bathwater!
There is a measurable reason for this and it's not because of productivity. It's about maintainableilty, consistency, and bug erradication. I'd love for you to read this paper Do Code Clones Matter? [0] to see what they have found.
Making it so people know how to:
* List all the featurs that a library will need
* Take those features and write them in a clean API
* Do it in the most clean language-specific way (ex Pythonic code)
* Distribution methodologies
* Maintainablilty and support of these libraries
* Using these, and others, libraries in larger applications
* Documentation & Technical writing
I'd really love it if you could email me and follow up after you read that paper and tell me what you think. My school username is jk369 and my school's email server is @njit.edu. (I've split this up to avoid spam)
I will look at your paper, but I think it depends what your target is, for students.
Many of our students go on to do PhDs. For that an understanding of deep algorithmics is much more important than being able to use and distribute a library, or building larger applications. They need, in their field of student, to be able to reimplement and understand many important difficult algorithms, not (for example) put together some node.js libraries.
However, there is a place for that kind of degree. Someone once said to me something which stuck with me: "You wouldn't try to merge a maths, and accounting degree, just because they both contain numbers", yet that's still what we do in computer science.
I just want to make sure, and state for everyone, that I'm far too lazy to do work that good. That's done by people much further along in their development of their profecian then I. Not my work just something that I think is good.
> Many of our students go on to do PhDs. For that an understanding of deep algorithmics is much more important than being able to use and distribute a library, or building larger applications
It depends on what their PhD or major is. Many CS majors here go into math and physics and they would have done better to learn how to write pythonic (or matlabic?) code and learn how to correcly design APIs. For instance, tonight I'm going to be rewriting a library from Python 2 to Python 3 and I have no way to tell if there's been any regression because of a lack of testing frameworks, consistentcy in APIs and lack of modularity. I'd be basically impossible for me to mock even single parts of this.
> They need, in their field of student, to be able to reimplement and understand many important difficult algorithms, not (for example) put together some node.js libraries.
I don't think left-pad is a good charictarization of my position here. I think that the hardest part of large scale software development is the architecture portion and that's mainly because very few people ever actually start large complex projects on their own and no universities offer courses in such a field that practicies that.
> However, there is a place for that kind of degree. Someone once said to me something which stuck with me: "You wouldn't try to merge a maths, and accounting degree, just because they both contain numbers", yet that's still what we do in computer science.
The moment you, or one of your coworkers, creates a major like that (Software Engineering and Developemnt or something) I'll be transfering over from my Computer Science degree. It's useless for anything but the name and the prestige that gets my foot in the door for a lot of very fun and interesting opportunities. I've had to hobcobble together everything I've needed to learn from a software perspective on reverse engineering, bare-metal systems devlopment, assembly, networking, game development, operating system development, web development, and many abstractions/patterns that go along with all of those. It was very difficult and I'd rather have given 30k/year over 4 years to a school who could teach me the "real" way from "professionals" and end up with a piece of extremely expensive framed paper that says my name and "degree" on it.
I'd also like for a school to hold my hand while exploring different paradigms.
Don't mandate a programming language for you assignments
I'd do them all in highly optimised x86 Asm, just because I can. ;-)
Not all students start at the same level; making the choice of language a free-for-all is just going to stretch that disparity even more. The ones at the top will naturally find ways to entertain themselves more, and the ones at the bottom will have no less idea of how to do things than copy-pasting code they found somewhere else (if the language doesn't matter, it makes that even easier...)
We were writing an interpreter using C++ which I'd rather have done in some Lisp-like languages.
On the other hand, I believe that doing something in an "unconventional" language for it is one way of improving your skills since you have to then apply true creativity and knowledge instead of just following an existing solution. Using a language which makes the task easy or even trivial doesn't really benefit the learning process.
> I'd do them all in highly optimised x86 Asm, just because I can. ;-)
I'd love to see someone do this because I'd say it'll be harder to do assignments I'd give out in x86 assembly then probably i686 or even ARM.
Most people would likely do everything in the language they want to learn or will need in industry. If you're just messing around then write it all in some obscure architecture like AP-101 or PDP-8 or even 4004. Maybe I just love the classics.
> Not all students start at the same level; making the choice of language a free-for-all is just going to stretch that disparity even more
That's why I said they should first be introduced to languages. That should be the first thing, day one, and continue until they get a basic idea of all the common features in programming languages.
> On the other hand, I believe that doing something in an "unconventional" language for it is one way of improving your skills since you have to then apply true creativity and knowledge instead of just following an existing solution
It may be fun but I wouldn't want to do it in production or on my grade.
That was me when I was in college. At the time my school was in the mid-teens for CS rankings although it is worse now. While I was there I worked heavily with C but also worked with C++, Java, List, MIPS RISC assembly, ML, Prolog, Ada, Fortran, Perl, Eiffel and a few others. For all of the languages that were supposed to be showing me a different paradigm in retrospect I didn't learn what I was supposed to.
Years later when I had both enough experience to appreciate these things as well as interest in programming languages I did start to grok all of this but it certainly wasn't due to my education.
To be fair, and I don't have your context on this, but looking at your link of the assignment for [0] it appears to me that this is more of an exercise in getting people comfortable with more advanced bash features, specifically looks like it relies fairly heavy on regex? I agree that BS4 is a better tool for this job, certainly, but there is perhaps a point in what is going on here too.
As far as the second one goes, I bet that has more to do with the professors particular familiarity with C than it does an understanding of what the best tool of the job for that is. I'll cede that point :)
Most of my classmates don't usually "learn" a language. They do an assignment by copying, hammering at the computer, or just asking for help. The basis of how university is set up is antithetical to the learning and exploration of new programming languages. This is based on one simple thing that most universities do and is very easy to fix.
If this one thing was done, we'd probably instantly see a much higher failure rate and a much hire quality of turnout. If early on in the curriculum students got a tour of every one of the big name languages and got to just choose the best tool for the job for the rest of their time at university there'd be a much closer approximation to how things (at least for me) work.If one of your projects is something like "scrape a webpage for X data" you wouldn't want to write that in a bash script (which I've been made to do [0]) I'd want to do that in Python with BS4. Or if your project is to write a parallel dot product function you wouldn't want to write that in C (which I've been made to do [1]). I'd want to write that in Julia.
Even in my class that I took for exploring programming languages we were forced to use C++. We were writing an interpreter using C++ which I'd rather have done in some Lisp-like languages.
Unfortunatly I've not been able to make the design decition to play with other language (in school) to see how they will better impact the development of these applications. I've not had to prototype stuff to see what language it will work best in (in school). These are decitions made for me.
I've found that this isn't how things work, at least for me, and I'm the one who is told "Do X" and I pick a way to do it. Whether it's by setting up a spreadsheet it a macro in it that generates the data or writing some real code. I get to choose the most elegant solution and I suffer the consequences then I didn't choose the most elegant solution since I have to my software when it breaks 2 years down the line.
[0] - https://web.njit.edu/~sohna/cs288/hw3.html [1] - https://web.njit.edu/~sohna/cs288/hw10.html