21

I teach as a private tutor and most of my students are prohibited to use techniques and/or language constructs that they haven't been taught!

There's a really broad variety of stuff that is prohibited like foreach-loops, switch-statements, functions/methods, etc.

What do you think is the benefit of this rule or why do most schools and universities have such a rule?

thesecretmaster
  • 4,785
  • 3
  • 21
  • 48
csabinho
  • 403
  • 4
  • 10
  • 10
    Sometimes I think it's just bad pedagogy. I'm reminded of [this stackoverflow question](https://stackoverflow.com/questions/56851693) where the restriction seemed particularly pointless and counterproductive. (It might have made sense for the *instructor* to demonstrate the "solution" without an array, to then motivate the use of arrays. But to require the student to write the code without using an array seemed, to me anyway, pedagogically insane.) – Steve Summit Sep 14 '19 at 16:38
  • 5
    Semi-related: requiring recursion for problems that are easier without it is quite common (often Fibonacci where naive recursive is just egregiously bad for performance). If the concept isn't introduced *too* early, there are problems where recursion is by far the easiest solution. [What are good examples that actually motivate the study of recursion?](//cseducators.stackexchange.com/q/4143) e.g. tree traversal, Ackermann function, or Merge Sort. All of these avoid solutions that look recursive but actually keep global state like a loop (especially in asm with state in regs). – Peter Cordes Sep 15 '19 at 19:58
  • 1
    Well, Fibonacci is still a quite OK problem for recursion, I've seen lot worse examples for recursion. – csabinho Sep 15 '19 at 20:38
  • 1
    @PeterCordes - it should be pointed out that recursive merge sort is mostly used for educational purposes. Most libraries use some variation of non-recursive merge sort for a stable sort. It becomes more clear in a when it is realized that a typical recursive merge sort is just generating and storing indexes on the stack, and that no merging takes place until two instances of the base case (sub-run size == 1) occur, while iterative bottom up merge sort skips all that recursion, and treats an array of n elements as n base cases of run size == 1, and immediately starts merging pairs of runs. – rcgldr Sep 16 '19 at 05:55
  • 2
    @PeterCordes, taken to extremes (as it is by e.g. the University of Cambridge) you can start by teaching programming in a functional language which doesn't have any way of looping *except* recursion. The counterpoint to "*too early*" would be that many iterative programs are implementing algorithms which are usually described recursively. – Peter Taylor Sep 16 '19 at 07:36
  • @PeterTaylor: Sure. I follow assembly-language tags on SO and my comment was 100% about imperative languages (and especially asm). Recursion is non-trivial to implement in asm (no compiler to save/restore locals for you across function calls). But Fibonacci makes a particularly bad example for asm recursion because it doesn't force you to distinguish passing/returning vs. just keeping a sum in a register that's effectively global, for a beginner just trying to make something work. Nonetheless, questions about asm recursive Fibonacci homework are more common than any interesting recursion. – Peter Cordes Sep 16 '19 at 15:05
  • @PeterCordes actually recursion is very easy to implement in assembly language. – Chris Stratton Sep 16 '19 at 22:08
  • @ChrisStratton: Yes, if you *know* assembly language then most things are easy. But the people that have trouble with it and post questions on SO often have other major holes in their understanding, e.g. of registers vs. memory and what instructions do. On a typical register machine (like x86), it's certainly more complicated than in C because you have to save/restore regists manually. And it might be the first non-leaf function students have written if they're using MARS to learn MIPS, where toy system calls do string or integer console I/O. RISCs use a link reg instead of pushing a ret addr. – Peter Cordes Sep 16 '19 at 22:19
  • @PeterCordes - all of the machines you mention have stacks. They may have certain optimizations like the LR but they all have stacks. – Chris Stratton Sep 16 '19 at 22:37
  • @ChrisStratton: Yes, but you have to use the stack manually. Nothing writes those push/pop and stack-pointer adjusting instructions for you. vs. higher level languages where you can do `int tmp = func(n-1);` and earlier local variables keep their values automatically. I think you're missing the point about *teaching* assembly language to people that start out with zero understanding of it. Of course everything is easy if you know how to do it, but it does require using multiple instructions in the right order and thinking about / knowing more stuff than in a higher level language. – Peter Cordes Sep 16 '19 at 22:49
  • @ChrisStratton: also, if you want to nit-pick, architecturally MIPS *doesn't* have a call stack. It's easy to implement one in software if you choose to, using its only addressing mode (`reg + imm16`), but not even HW interrupts use any register as a stack implicitly. Of course the standard software conventions on MIPS do define a register as the stack pointer, so if you're including that as part of MIPS then yes it has a stack. Anyway, saving/restoring a link register correctly is an extra complication that creates more ways to have infinite loop bugs for beginners. (Look at SO's MIPS tag) – Peter Cordes Sep 16 '19 at 22:55
  • @PeterCordes all of that and not a word about branch delay slots? I'm disappointed :-) More seriously, most of what you mention is a challenge fundamental to assembly on these platforms *at all* - recursion isn't notably harder than more conventional function calls. – Chris Stratton Sep 16 '19 at 23:42
  • @ChrisStratton: Agreed! But before doing recursion, some students have only written trivial leaf functions that can get away with clobbering any/all registers. So at least some students don't really understand the basics of functions yet, and/or recursion is teaching that, too. (And BTW, MARS defaults to simulating a MIPS without branch delay slots. Instructors using MARS/SPIM to teach intro-to-assembly use that variant of MIPS, along with the toy I/O system calls instead of non-existent libc function calls.) Selection bias: only the most confused/lost or lazy post on SO about such basics. – Peter Cordes Sep 17 '19 at 00:28

9 Answers9

37

Rules like this are generally instituted because the teacher is attempting to teach a concept made moot by one of these constructs. For example, as a teacher, if you're teaching bitwise operators and ask students to implement absolute value, it simply makes no sense to permit the students to use whatever library function does absolute value. You're teaching bitwise operators, and the fact that they know of the library function doesn't help them learn bitwise operators.

I believe that because you're asking here, the reason for the prohibition isn't as obvious as in my example, but my guess (without knowing the specifics of the situation) is that the prohibited constructs are not what are being taught so, for that course, the students knowledge of a more advanced concept is irrelevant to the subject matter being taught.

thesecretmaster
  • 4,785
  • 3
  • 21
  • 48
  • The first sentence of your second paragraph is spot-on. In most cases I suspect that those constructs were just forgotten... Also i don't see why functions/methods are taught that late, but that's almost another topic... Also I'm not really sure if there is a clear plan behind this or if it is more about authority than didactics, or in other words: "Rules are rules and that's it! Just follow them and don't ask why they have been set up. If you don't follow them, you disrespected the teacher and will be penalized"! – csabinho Sep 13 '19 at 20:36
  • @csabinho Both are definitely true. Usually, it's pretty easy to see - what was the latest thing the teacher has worked with? If they don't keep up with any new methodologies and technologies, they probably prohibit things just to avoid having to learn anything new. If they do learn new things (and teach them when appropriate), they probably have didactic reasons for the prohibitions - and shouldn't have any problem explaining why a particular approach is forbidden. I've met plenty of teachers of both kinds. – Luaan Sep 16 '19 at 12:52
23

Where it stems from is, of course, because the lab is not the thing that the instructors want solved. After all, the posed lab problem is not unsolved, and your solution will only be unique (if at all) in some surface way. This is the source of the feeling that people have that the restrictions are unreasonable: they feel like solving the lab is somehow the purpose of the assignment, and therefore any high quality solution is to be praised. But, of course, that's not the point at all.

So if solving the problem isn't the deeper purpose of a lab, then what is? Typically, we are teaching an algorithm, a language feature, a data structure, or some other mental model of how something works. The lab is conjured as something that lends itself to that problem, and that is the goal of the instruction. I want to engender mastery of linked lists, or stack management, or two-dimensional arrays, or memory management, or... whatever the focus is.

The lab problem itself is entirely secondary, even if it does not in any way feel like this to the student. The problem posed to students is simply meant to provide a rich environment to play around with the learning target, and to gain some measure of experience wrestling with it.

The problem that we run into, then, is that there is no problem that cannot be solved in many ways. I can search as hard as I might for a problem that would be much, much harder to solve in a manner perpendicular to the purpose of the lab, and sometimes I will have some success. But sometimes I will not, because sometimes no such problem exists.

There exists no problem that can be solved with a linked list that cannot also be solved with an arraylist. I could provide starter code to try to force my approach, but that simultaneously increases the difficulty of creating the lab while decreasing the thought that must go into solving it.

A blanked ban, such as "you may use no bang operators in your Racket lab" is an imperfect solution, but all of the solutions are imperfect, and sometimes a ban feels like the least of the evils.

This is not a blanket defense; such bans can be careless, or needless, or clumsily done. I try hard to avoid them in my own instruction, but I don't always succeed. If it seems unfair to restrict my students' approach, it is also unfair to my students if they don't delve far enough into the course material because they originally thought of a different solution, and they just stuck with it. That keeps them on their own familiar territory and cheats them of the chance to learn the material in the course, which they may well need in their next course, or later on in their life.

Ben I.
  • 32,726
  • 11
  • 68
  • 151
  • 1
    Even though I completely see your point, my point, which was maybe not made clear enough in my question, is why students are forced to do typical "don't try this at home"-programming because of those restrictions. Also mostly I don't have the feeling that the teachers are following a clear didactic plan which requires to solve specific examples with specific constructs but it's more about their authority, which is undermined if their students leave their path and start learning on their own(and also that some constructs are just forgotten, but that's another topic). – csabinho Sep 13 '19 at 23:38
  • Getting students used to obeying arbitrary authority is its own benefit, they are likely going to need to do so much of their working life, even if they aren't working as programmers. The worst example of this I encountered as a student was an instructor who flat forbade use of the C "->" operator even after it was encountered in the book. He insisted that "(*ptr).member" constructs be used instead. That one I never have figured out other than it being an ego trip. – SoronelHaetir Sep 14 '19 at 04:58
  • 5
    @SoronelHaetir You mean that this is a way of saying "life is ****, learn it early!"? ;-) – csabinho Sep 14 '19 at 07:33
  • 2
    @csabinho Learning to deal with the fact that life is **** is a more important accomplishment than learning some particular programming technique, IMHO. The programming technique may or may not be transferrable to your next programming language. Your knowledge about life is guaranteed 100% transferable to every situation, up to and including death. – alephzero Sep 14 '19 at 13:24
  • 2
    "There exists no problem that can be solved with a linked list that cannot also be solved with an arraylist" <-- sure there does. Ones for which there are constraints on availability of storage/in-placeness. – R.. GitHub STOP HELPING ICE Sep 14 '19 at 15:37
  • 8
    @SoronelHaetir "Getting students used to obeying arbitrary authority is its own benefit" Where I went to school, my maths/latin/philosophy teacher who started at the school fresh from university when I entered school, and was headmaster by the time I left, prided himself in teaching the students two important abilities: To determine whether authority is right or wrong, and to fight authority when it is wrong. – gnasher729 Sep 15 '19 at 22:48
  • 3
    Ironically, arbitrariness is not necessarily a bad thing, as a learning exercise. There's actual value to making up a language or computation machine with *absurd* and unfamiliar rules, and learning to work within those, as it teaches precisely the kind of plasticity of thought needing to find the best solution to real problems - especially those problems where conventional techniques fail, or where past decisions (which may have been unwise, but now are set) constrain current options in a way that rules out the usual solutions. – Chris Stratton Sep 16 '19 at 23:29
11

I think that the answer of thesecretmaster is correct but let me add a bit of advice to an instructor who would do this. Just as you, the OP, wonder yourself, the rule doesn't seem to make a lot of sense and it won't make sense to students either. It may cause resentment.

So, if an instructor wants to use a rule like this then, I think that a general rule against using things not yet taught is foolish. However, you can achieve the same result by carefully stating the problem you want solved. So, for example, following thesecretmaster, instead of asking for the students to compute the absolute value ask them to compute the absolute value using only the bitwise operators. In other words, put the specific restriction into the question itself.

This brings up an important teaching and learning technique called "creativity under constraint". Some wood working artists, for example, use only hand tools, forgoing power tools. Furniture makers I've known do this. The restricted set of tools forces them to make better use of the tools that the do use, becoming more skilled in the process. But, to impose it on someone else requires that you make it clear why it is a good idea to do this.

I've discussed Creativity Under Constraint here in the past in other contexts. See this post and this other one.

Buffy
  • 35,808
  • 10
  • 62
  • 115
  • 1
    “the rule doesn't seem to make a lot of sense and it won't make sense to students either” Why? As an ex CS student and now software developer, the rule made a lot of sense to me. E.g. if the teacher wanted us to learn for loops by implementing multiplication or exponentiation, **of course** they would say "you cannot use the `*` operator". – Andrea Lazzarotto Sep 14 '19 at 22:11
  • @AndreaLazzarotto, the simple prohibition _without reasoning_ is what doesn't make sense to them. You have to motivate the requirement to avoid the reaction "this is stupid". – Buffy Sep 14 '19 at 22:16
  • 1
    The reasoning is obvious. If there exist libraries or "more convenient" methods to solve a problem, depriving it from educational value, the instructor needs to forbid such methods. Any university student is able to understand this. – Andrea Lazzarotto Sep 14 '19 at 22:28
  • @AndreaLazzarotto The reason might be obvious in specific cases but not as a general rule. If you have this as a general rule the only explanation I have for this is the rule that stands above all others: obey the authority! – csabinho Sep 15 '19 at 04:30
3

In addition to the good reasons given in the other answers:

Sometimes students find code on the Internet that they can just copy into the assignment without understanding. In a coding class it seems reasonable to require students to understand the code they submit.

As an instructor I would consider telling students that if they use techniques not covered in class they may be required to explain these techniques to the instructor.

paw88789
  • 139
  • 2
  • 1
    Well, yes, of course, they should understand what they are doing. But who says that they understand the code if they copy code that just uses techniques and language constructs that are covered by the lessons? And on the other hand, if students know what they are doing, why would you prohibit the use of anything not covered by the lessons? Of course in specific cases you want the students to solve it in a specific way, and everybody will understand this, but that's no general rule. – csabinho Sep 15 '19 at 04:26
  • 1
    @csabinho Well at least they would have to study the code long enough to determine whether it used appropriate techniques. – paw88789 Sep 15 '19 at 06:22
  • 1
    Or copied it from classmates who wrote it themselves... I'm not really seeing a big difference...if any! – csabinho Sep 15 '19 at 18:02
2

Benefit: forces students to stay with and practice required concepts of the unit/exam or subset of the course.

user8425
  • 21
  • 1
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackexchange.com/rooms/98814/discussion-on-answer-by-user8425-whats-the-benefit-of-prohibiting-the-use-of-te). – thesecretmaster Sep 18 '19 at 14:14
2

There are some great answers and discussion here about reasons why a teacher may forbid certain syntactic constructs for a given assessment. I have an additional perspective on it.

A student cannot possibly learn the entire language all at once. Not only is there syntax to learn, but also how to put the pieces together into coherent programs. It is a lot to learn for a novice programmer. So the language must be introduced incrementally, starting with basic constructs and layering more advanced ones on top of them. Whether such constructs really are more "advanced" is informed by the curriculum and pedagogy.

Some students may have more advanced knowledge. Perhaps they read ahead in the book; maybe they have had prior programming experience; it could be they saw something on Stack Overflow and they understood it. Whatever the reason, some students may have knowledge that others do not. By restricting what constructs can and cannot be used in an assignment, the instructor is leveling the playing field.

Most students are barely able to keep up with the syllabus and know only what information has been presented to them. Others may know more. The restrictions are intended to ensure that everyone is playing by the same rules. The instructor has carefully designed the assessments so they are solvable using only the concepts students are expected to have at that point in the curriculum. To some students that may feel like a straightjacket, but they need to keep in mind that most other students won't feel constrained at all because they don't know there is anything else.

Barry Brown
  • 303
  • 2
  • 8
  • 2
    Why would an instructor want to "level the playing field". Is learning a competitive sport like foot ball? I would certainly never do it for that reason. More advanced knowledge is a good thing. Again, an exercise is seldom about "getting an answer", but about learning something important. – Buffy Sep 17 '19 at 20:23
1

Students need to learn how to deal with strict rules, imposed by their programming environment.

In real life, the rules are dictated by the limit of your programming language or processor. Easy example: You cannot use an instruction, that is not implemented in your microprocessor. So you need to stick to the rules of your processor.

When you now use a common programming language for teaching, you cannot teach every feature of it, so you won't hit any limitation of a language like C++. Still the student needs to be able deal with such limitations. So you for example tell the student "Implement a factorial without using the factorial function in the standard library", to impose an artificial limitation.

This seems silly, as the standard library factorial may be more optimized (e.g. using iteration when your lecture was about recursion or even optimizing on a specific processor), but later in real life, the student will encounter more complicated tasks, that are not covered by any existing library.

This requires that he learned how to implement something himself instead of always relying on existing libraries. In the end, someone build the library, when there was no existing library for this function. And this someone may be a former student of you.

allo
  • 119
  • 3
  • 2
    I'm quite sure that you are talking about a completely different scenario than I am! I am talking about prohibiting everything that has not been taught, and of course on the other hand allowing everything that has been taught.You are talking about specific rules! Explicitly prohibiting certain things for certain tasks makes a lot of sense, of course! Prohibiting everything and always makes no sense at all! – csabinho Sep 16 '19 at 08:56
  • 2
    And I am talking about language constructs like switch and foreach. Those are rarely taught in the schools which I have to deal with and would be really useful. – csabinho Sep 16 '19 at 09:08
  • I am thinking of for example an restricted assembler dialect to teach how to work with its instructions. Or when you're thinking of foreach, maybe how to implement a loop using comparision and jump instructions. I do not know lectures, that really forbid foreach directly, but in the context of e.g. an didactic assembler dialect I see a point in for example not allowing a multiplication instruction, so the students need to implement it themself. – allo Sep 16 '19 at 18:06
  • @csabinho - it doesn't really matter what the restrictions are, it matters that *dealing with restrictions* is a fact of life in programming. Because you are not attending the course yourself, you may not be familiar with them as ground rules and so constantly trip over them while proposing things you consider ordinary. But the thought process of being able to work within *any* set of restrictions is key: **never trust someone who can only solve a problem in a single way** . Many areas within CS require drastic changes of thinking to adopt, and changing thinking is an important exercise. – Chris Stratton Sep 16 '19 at 20:36
  • @ChrisStratton I'm talking mostly about beginners and restricting them to use anything that wasn't learned during the lessons stops them from being autodidacts, which is also an absolutely essential skill in programming life. Those restrictions often reach the point you are talking about: being only able to solve the problem in a specific way, and also, as mentioned above, it kills the drive to learn something new and teaches to stay on the given path and don't look to the left and right and don't strive to learn more and be ahead of what's taught, if you don't want to get punished! – csabinho Sep 16 '19 at 20:55
  • What you are not understanding is that the point of being forced to solve the problem in a specific way *at a given point in a course* is to **make sure you can really use that way**. Then you move on and solve it in a different way. If the choice is always free, *students merely stick with their preferred familiar way* and never have to learn about the alternatives. There's also the distinct skill of learning to think in terms of the offered tools. The problem here is that **you are trying to re-write the actual instructor's syllabus** - when you aren't even a participant in the course(!) – Chris Stratton Sep 16 '19 at 22:05
1

To give a more detailed example to @thesecretmaster's answer:

Sometimes language constructs hide the underlying complexity. That might be beneficial when coding, but counterproductive when teaching. Take these loop examples:

for (int i=0; i<n; ++i) {
  // example statement
  array[i] = 5; 
}

In many languages, this can be written as a for-each loop (sometimes known under different names), such as:

for (int variable : array) {
  variable = 5;
}

The second code example makes it way harder to explain the concept of a loop invariant. Questions such as:

  1. What is the last element, array[n] or array[n-1]?
  2. How can you run the loop only for elements after the 3.?
  3. How can you proof that the loop terminates?

become much harder to explain when students simply use the foreach feature.

knallfrosch
  • 111
  • 2
  • A foreach-loop does something else than a for-loop and you can't change the array within a foreach-loop, at least not without using it like a while-loop and have your own counter which is incremented in the loop body! – csabinho Sep 16 '19 at 13:56
  • On the other hand, the foreach loop may be easier to understand if introduced first simply because those questions can be deferred until later. I'm not suggesting that the questions aren't important; they may just be inappropriate *right now.* – Barry Brown Sep 17 '19 at 19:41
1

This question was asked 3 years ago when ChatGPT didn't exist yet. Nowadays I would say (in addition to several excellent answers above) that the use of techniques not already taught is a sign that the student got some LLM to generate the answer. The answer from a chatbot can very well be correct, but it will also be more sophisticated than the student could have come up with on their own.

So you can either not allow this, or insist that the student be able to justify every single line in their code.

Victor Eijkhout
  • 1,423
  • 5
  • 13