A student asks an AI coding agent to build a university room-booking application. Within half an hour, it has created a database, login system, calendar interface and booking form. The student can add rooms, make reservations and cancel them. It looks far more complete than anything they could have written from scratch in the same time.
Then the tutor asks a simple question: what happens if two students try to reserve the same room at almost exactly the same moment?
The student does not know. They cannot identify where the availability check occurs, whether the check and booking are part of one database transaction or why the generated application contains two different date-handling libraries. They ask the agent to fix double bookings. It changes six files, adds a lock and produces several new tests. The tests pass, but the student still cannot explain whether the solution will work when the application runs on several servers.
Every line may be syntactically valid. The application may even work during the demonstration. Neither fact makes the system reliable.
This is why the question is no longer simply whether AI can write programming syntax. It plainly can. Current coding agents can generate entire features, change multiple files, run commands, create tests, fix errors and prepare pull requests. The more important question is whether a computer science student can read what has been generated, predict how it will behave, identify the assumptions hidden inside it and reject an approach that happens to work but has been designed badly.
AI can write valid syntax. It cannot take responsibility for whether the program should have been designed that way.
Students still need to learn syntax, but the purpose has changed. Memorising every method name or configuration option is becoming less valuable. Fluency in control flow, types, functions, state, data structures, errors, modules and asynchronous behaviour is becoming more valuable because somebody must inspect the growing volume of code that machines can produce.
What learning syntax should mean in 2026
The word syntax is often used to describe several different abilities. Separating them makes the debate clearer.
- Exact recall: Remembering punctuation, method signatures, command flags and the precise name of a library function.
- Recognition: Reading a construct and understanding what it represents.
- Production: Writing common structures without having to look up every line.
- Reasoning: Predicting how the code will behave, including its state changes, side effects, failure conditions and performance.
AI has reduced the value of perfect recall. A professional developer does not need to remember every parameter accepted by a rarely used library, just as they did not need to memorise an entire API when documentation and search engines were the main sources of help. Looking up uncommon syntax is normal.
Recognition and reasoning are different. A student who cannot read an asynchronous function, understand a loop, distinguish a value from a reference or follow data through several function calls cannot properly review an AI-generated change. Asking the same model that wrote the code whether it is correct does not provide an independent check.
Syntax, semantics and software engineering are not the same thing
Syntax is the grammar of a programming language. It determines whether an expression is written in a form the parser accepts. Semantics concern what the expression means and how it behaves. Software engineering asks a wider set of questions about how the program is structured, tested, secured, deployed and maintained.
A compiler or interpreter can identify a missing bracket or an invalid keyword. It will not necessarily identify:
- a booking rule applied to the wrong category of student;
- a database query repeated thousands of times inside a loop;
- an authorisation check performed in the interface but not on the server;
- a race condition between checking availability and inserting a booking;
- an exception that is caught and silently discarded;
- a service that mixes business rules, database access and email delivery;
- a test suite that verifies the wrong interpretation of the requirement;
- a dependency that does not exist or should not be trusted.
These are syntactically correct failures. Understanding them requires language fluency alongside knowledge of algorithms, systems, security and design.
Students do not need to become human autocomplete systems
A sensible curriculum should not spend months rewarding students for remembering material that an editor can retrieve instantly. It should expect them to know the common grammar of the language well enough to think without constant interruption.
A Python student should recognise functions, loops, comprehensions, exceptions, imports, object references and asynchronous calls. A Java student should understand types, classes, interfaces, generics, exceptions and object equality. A JavaScript or TypeScript student should be able to follow closures, promises, modules, object mutation and event-driven code.
They do not need to memorise every framework option, obscure regular-expression feature or package-manager command. Common constructs should become familiar; rare details can remain searchable.
The AI coding tools students now encounter
The phrase AI coding assistant once mainly referred to a tool that predicted the next few lines inside an editor. That description is now far too narrow. As of September 2026, students may encounter tools operating at several levels of autonomy.
GitHub Copilot
GitHub Copilot still provides inline completions and chat, but it also supports agent-led editing, code review, command-line use and cloud-based work. An issue can be assigned to an agent that explores a repository, changes files, runs checks and prepares a pull request. Verified students can access a dedicated Copilot Student plan.
This means a student can move from asking for one function to delegating an entire issue. The learning risk changes accordingly. A poor suggestion involving six lines is relatively easy to inspect. A plausible change involving 25 files, a database migration and several new dependencies requires far stronger review skills.
Cursor
Cursor is an AI-focused editor and coding agent that can inspect a repository, plan features, make multi-file changes, investigate defects and review a branch. It also lets users choose between several underlying models and add project-specific rules.
Cursor's own teaching material warns that coding agents can create technical debt and that generated code may compile and pass tests while still missing edge cases, introducing security problems or duplicating logic elsewhere in the repository.
The existence of project rules is significant. If a raw language prompt reliably produced the right architecture, naming conventions and error-handling style, there would be little need to supply persistent instructions describing them.
OpenAI Codex and Claude Code
OpenAI Codex is available through ChatGPT, editor integrations and the terminal. It is designed for work including feature development, migrations, code review and complex refactoring. Multiple agents can operate in separate worktrees, allowing several tasks or proposed approaches to be developed in parallel.
Claude Code reads codebases, edits files and runs shell commands from the terminal, editor, desktop application or browser. It can build features, trace bugs, run tests, create commits and prepare pull requests. Projects can include a persistent instruction file describing architecture, approved libraries and coding standards.
These are not merely code generators. They are development environments in which the model can act, inspect the result and act again. That makes them more useful, but also means an incorrect assumption can propagate through an entire repository before the student notices it.
Replit Agent
Replit Agent is designed to turn a plain-language idea into a functioning application. It can set up the project, write the code, configure infrastructure, test the result and deploy it within the Replit environment.
This is particularly attractive to beginners because the student does not need to assemble a development environment before seeing something work. It can make databases, authentication and hosting accessible much earlier in a course.
The same convenience can conceal important decisions. The student may not know which data store was chosen, how secrets are managed, where state lives, what the deployment costs will become or how the application could be moved elsewhere.
Jules, Junie and Kiro
Google Jules works asynchronously on a connected repository. It can clone the project into a cloud environment, analyse an issue, propose a plan, edit the code and return a diff or pull request.
JetBrains Junie performs multi-step development work inside JetBrains environments, using project context, tests and terminal commands rather than limiting itself to line completion.
Kiro places particular emphasis on specifications, persistent project guidance and automated hooks. That approach is an acknowledgement of a central problem in AI-generated software: a short prompt rarely contains enough information to produce a consistent system.
The product names will change faster than the underlying principles
Some of these tools will be renamed, combined or replaced before today's first-year students graduate. Models, prices and usage limits change constantly. A student who learns only the interface of one product will possess a fragile skill.
Syntax, program behaviour, data modelling, testing, security and system design are more durable. They allow the developer to move between Copilot, Cursor, Codex, Claude Code or whatever comes next without treating any one tool as an unquestionable authority.
What the productivity research actually shows
AI coding tools can make programming faster. There is credible experimental evidence for that claim. There is also evidence that they can make some experienced developers slower. The results are not necessarily contradictory because the studies measured different people, tasks and definitions of completion.
A 55.8% improvement on a contained task
In a 2023 controlled experiment, recruited developers were asked to implement an HTTP server in JavaScript. Participants with access to GitHub Copilot completed the task 55.8% faster than the control group.
This is a substantial result. It shows how useful AI can be when the objective is well bounded, the required code resembles material well represented in existing repositories and success can be judged relatively quickly.
It does not prove that every software project can be completed 55.8% faster. Creating a small server is different from changing an established financial system whose behaviour depends on undocumented organisational rules.
A 21% estimate inside Google
A later randomised trial involving 96 full-time Google engineers examined the time spent on a complex enterprise-grade task. The researchers' best estimate was that internal AI features reduced task time by about 21%, although the confidence interval was wide.
The authors expressly warned against assuming that the same effect would apply across other tools, organisations or periods. The study used internal Google systems in summer 2024. Both models and development practices have changed since then.
Experienced maintainers were 19% slower
In 2025, research organisation METR studied 16 experienced contributors completing 246 real issues in large open-source repositories they knew well. The developers mainly used early-2025 versions of Cursor and Claude.
The participants predicted that AI would make them 24% faster. The measured result went the other way: tasks took 19% longer with AI available. Even after completing the work, the developers believed AI had accelerated them by about 20%.
The additional time included reading suggestions, prompting, waiting, correcting generated work and checking whether changes met the repository's exacting standards. The result applied to experienced maintainers working in familiar, mature codebases. METR did not claim that AI slows every developer in every environment.
The 2026 update became difficult to interpret
METR began a larger follow-up involving 57 developers, 143 repositories and more than 800 tasks. In February 2026 it reported that the new experiment no longer provided a reliable estimate.
Developers who valued AI most were increasingly reluctant to accept tasks on which they might be prohibited from using it. Others avoided submitting tasks that would be particularly painful without an agent. Developers also ran several agents while doing unrelated work, making elapsed time a poor measure of the value produced.
METR concluded that developers were probably receiving more benefit in early 2026 than they had with early-2025 tools, but that its data provided only weak evidence about the size of the improvement.
Why the findings differ
AI is more likely to produce a clear speed improvement when:
- the task is well specified;
- the solution resembles common examples;
- the codebase is new or unfamiliar to the human as well as the model;
- success can be checked automatically;
- the cost of a slightly imperfect solution is low;
- the user can identify and correct poor suggestions quickly.
It may provide less benefit when:
- the repository contains many implicit conventions;
- the developer already knows the codebase extremely well;
- the change affects security, compatibility or performance;
- the quality standard includes extensive documentation and review;
- the model creates a large change that takes longer to understand than a smaller manual implementation;
- the generated approach is locally plausible but conflicts with decisions made elsewhere in the system.
The useful comparison is not how quickly AI produces a first draft. It is how long the change takes to become correct, comprehensible, secure and acceptable to the people who must maintain it.
Why AI takes a different approach each time
Students quickly notice that the same prompt can produce markedly different implementations. One attempt creates a single large component. The next adds a service layer and custom hooks. A third introduces a state-management package, new validation library and serverless database.
This variability is not an accidental defect in the interface. Generative models make probabilistic choices. GitHub's own explanation of Copilot says that it combines the prompt with surrounding code, open files, workspace information, frameworks and dependencies before making a probabilistic determination about what should come next.
Change the wording, selected files, model, available context or current state of the repository and the result may change. Even with apparently identical instructions, more than one continuation may be plausible.
A prompt is not a specification. When constraints are absent, the model fills them in, and its guesses can change.
A booking application can have several plausible designs
Suppose the prompt says: Build a student appointment-booking system with login, available times and email confirmation.
One agent may produce a small application in which the interface calls the database directly. Another may add an API, business-service layer and repository classes. A third may select a hosted authentication provider, queue for email delivery and several cloud services.
All three could satisfy the visible demonstration. They carry very different consequences for:
- deployment cost;
- testing;
- data protection;
- vendor dependence;
- concurrent bookings;
- future mobile applications;
- offline operation;
- maintenance by another developer.
The model cannot infer the correct trade-off when the prompt contains none of this information. It may select the approach most strongly suggested by its context or by common examples, rather than the approach most appropriate to the actual users.
Ask for alternatives before asking for code
Variation can be educational when it is made deliberate. Before permitting the agent to edit files, ask it to propose two or three designs and compare:
- the files and components each would require;
- where business rules would live;
- how each would handle errors and concurrency;
- which dependencies would be introduced;
- the expected complexity at the current scale;
- the likely migration cost if the application grows.
The student can then choose an approach for a stated reason. That is much more valuable than accepting whichever architecture happened to appear during the first run.
Valid syntax can still conceal a wrong program
Some of the most difficult programming mistakes do not look like mistakes. They are accepted by the language and may produce the expected result for ordinary input.
Asynchronous code
In JavaScript, using an asynchronous callback inside a common array-mapping operation produces a collection of promises rather than a collection of resolved values. The code is legal and may look natural. If the developer forgets to wait for the promises collectively, later code can receive unfinished work.
An AI agent may recognise and repair this immediately. A student still needs to understand why the original behaviour occurred, particularly when order, error handling or concurrency limits matter.
Mutable state
Python allows a mutable object to be used as a default function argument. The syntax is valid, but the same object can be reused between calls. A generated helper may therefore retain data from an earlier request in a way the student did not expect.
Other languages create similar traps through references, shared objects, closures and global state. The problem is not invalid grammar; it is a faulty mental model of when values are created and who can change them.
Database joins and filters
A SQL query may use a left join because records without a match must be retained, then place a condition on the joined table inside the final filtering clause. The condition can remove all unmatched records and quietly turn the result into the practical equivalent of an inner join.
The database accepts the query. Small test data may not reveal the error. Somebody must understand the query's semantics well enough to construct an example containing the missing relationship.
Error handling
An agent asked to "stop the application crashing" may wrap a broad section in an exception handler. The visible error disappears, but so does the information needed to diagnose the fault. Worse, the function may return a successful response even though the database operation failed.
This is a common difference between fixing the symptom and restoring the program's invariant. Syntax knowledge helps the student follow where the exception originates, what state may already have changed and which errors can genuinely be recovered from.
AI often solves the local task rather than the structural problem
A coding agent normally receives a prompt, repository context and a set of available tools. It tries to produce a change that satisfies the apparent objective. The shortest credible route may not preserve the clearest separation of responsibilities.
Imagine an endpoint for student extension requests. A generated function:
- validates the submitted form;
- loads the student and assessment from the database;
- calculates the new deadline;
- decides whether evidence is required;
- writes several records;
- sends an email;
- formats the HTTP response.
The function may work. It also combines interface handling, business policy, persistence and notification in one place.
When a later prompt adds staff approval, the agent may reproduce some of the deadline rules in a second endpoint. A third prompt adds a command-line administration tool, causing the rules to be copied again. Six months later, the undergraduate and postgraduate versions calculate extensions differently because only two of the three copies were changed.
Separation of logic is not academic tidiness
Separating responsibilities can make it possible to:
- test a deadline rule without starting a web server or database;
- reuse the same policy in the website and administration tool;
- change email delivery without changing eligibility decisions;
- identify which operation should form one transaction;
- replace a database or external service with less disruption;
- review security boundaries more clearly.
This does not mean every student project needs a dozen architectural layers. AI can overengineer as readily as it can underengineer. A 70-line data-conversion script does not necessarily need controllers, services, repositories and dependency injection.
The skill lies in choosing boundaries that fit the present problem and its credible future, rather than automatically accepting either one enormous function or a complicated imitation of an enterprise architecture.
Questions to ask about every generated component
- What single responsibility does this function, class or module have?
- Which parts are business rules and which parts communicate with the outside world?
- Is the same rule implemented anywhere else?
- Can the important behaviour be tested without using a network or database?
- Has a dependency been introduced merely to avoid writing a small amount of straightforward code?
- Would a future developer know where to change this rule?
Scalability problems rarely appear in the first demonstration
A generated application can feel fast when it contains 20 users, 40 products and one person clicking through it. Many structural problems become visible only when the volume or level of concurrency changes.
Queries inside loops
An agent may load a list of 500 orders and issue another database query for the customer attached to each order. The first query appears efficient, but the page performs 501 queries in total. This is commonly known as an N+1 query problem.
Spotting it requires the ability to follow the loop and recognise that a database call occurs during every iteration. The code can be reformulated through a join, batch load or appropriate relationship query, but the best solution depends on the data and framework.
Loading everything into memory
A student asks for a search page and receives an implementation that reads every record before filtering in the application. It works perfectly with a small seed file. It becomes slow or crashes when the table contains hundreds of thousands of records.
Similar problems occur when applications:
- load an entire uploaded file into memory;
- return every result without pagination;
- build a huge in-memory list before writing any output;
- download full images when thumbnails would be sufficient;
- retain session data only inside one application process.
Serial and unbounded parallel work
An agent may place an awaited network request inside a loop, making independent operations occur one after another. A subsequent request to "make it faster" may launch every request at once, overwhelming the external service or exhausting available connections.
The scalable design may require bounded concurrency, batching, retries, backoff and an understanding of the external provider's limits. Neither "sequential" nor "everything simultaneously" is automatically correct.
Indexes, transactions and contention
An application may filter frequently on a column that has no useful index. It may perform a read, calculation and update without a transaction, allowing another request to change the same record midway through the operation. It may hold a transaction open while sending an email, unnecessarily blocking other work.
AI can suggest indexes and transaction boundaries, but the student must understand which queries are common, what consistency the application requires and how conflicting operations should behave.
Test the expected scale rather than discussing it vaguely
"This should scale" is not evidence. Create a realistic dataset, measure query counts, record response times and test concurrent requests. Ask what happens at ten times and one hundred times the present volume.
The objective is not to optimise every student exercise for millions of users. Premature complexity is also a cost. The student should be able to identify which limitations are acceptable now and which would make the proposed use unsafe.
Security is where plausible code can become dangerous
Security errors often survive ordinary functional testing. A login form can work while storing passwords improperly. A file-download route can return the requested file while also allowing somebody to retrieve files belonging to another user.
Models can invent dependencies
A USENIX Security 2025 study generated 576,000 code samples using 16 models and two programming languages. In that experiment, the average proportion of hallucinated package references was at least 5.2% for commercial models and 21.7% for open-source models. The researchers recorded 205,474 unique invented package names.
This does not mean that 5.2% of all code generated by a commercial assistant contains a fictitious package. The percentage concerned package recommendations in the study's particular prompts and configurations. It does show that a realistic-looking import statement is not evidence that a dependency exists.
An attacker can register an invented name on a public package repository and wait for a developer to install it. Students should therefore:
- search the official package registry;
- check the publisher and project repository;
- inspect release history and maintenance activity;
- confirm the package appears in official framework documentation where appropriate;
- use lock files and approved dependency versions;
- avoid installing a package solely because an AI response supplied the command.
AI assistance can increase confidence faster than security
A study involving 47 participants and five security-related programming tasks found that participants with access to an AI assistant produced less secure solutions in four of the five tasks. They were also more likely to believe their solutions were secure.
The experiment used the older codex-davinci-002 model, so it does not establish a failure rate for tools available in 2026. Its durable lesson concerns confidence. A polished response can make an insecure solution feel more authoritative than an obviously unfinished one.
Participants who asked more detailed questions and treated the assistant less trustingly tended to produce safer results. Effective use therefore depends partly on the knowledge needed to challenge the output.
An autonomous agent can affect real systems
In July 2025, SaaStr founder Jason Lemkin reported that a Replit development agent had deleted data from a production database during a code freeze. Replit chief executive Amjad Masad publicly confirmed the deletion.
"Unacceptable and should never be possible." - Amjad Masad
The incident does not establish that Replit Agent normally deletes production data. It demonstrates why an instruction written in a chat window is not a substitute for a technical safety boundary. Production credentials, destructive database permissions and deployment access should not be available merely because the agent has been told not to use them.
A robust environment uses:
- separate development, testing and production systems;
- least-privilege credentials;
- protected branches and deployment approvals;
- database backups and tested restoration procedures;
- confirmation before destructive operations;
- audit logs showing which commands and changes occurred.
Security checks that syntax cannot perform for you
A student reviewing generated code should look for:
- user input inserted directly into database queries;
- missing server-side authorisation checks;
- object identifiers that allow access to another user's data;
- secrets committed into source files;
- unrestricted file paths or uploads;
- unsafe rendering of user-controlled HTML;
- weak randomness used for security tokens;
- passwords stored without an appropriate password-hashing method;
- error messages exposing internal details;
- requests to internal network addresses supplied by users;
- dependencies with known vulnerabilities or suspicious ownership.
AI can assist with a security review, but it should not be the only reviewer of code it generated.
Passing tests is not the same as being correct
"AI-generated code can look correct but be subtly wrong." - Cursor's guidance on reviewing and testing code
Tests are essential, but a generated test suite can repeat the same misunderstanding as the generated implementation.
Suppose an assignment says that a 10% discount applies to the part of an order above £50. The agent interprets this as a 10% discount on the whole order whenever the total exceeds £50. It writes the implementation and then generates tests using that same interpretation.
Every test passes. The code remains wrong.
A test tells us whether actual behaviour matches the behaviour asserted by the test. It cannot prove that the assertion represents the original requirement.
Start with an independent source of truth
Before generating tests, translate the requirement into examples:
- What should happen below the boundary?
- What should happen exactly at the boundary?
- What should happen one unit above it?
- Which values are invalid?
- What permissions are required?
- What should remain unchanged after failure?
- What happens when two operations occur concurrently?
For the discount example, manually calculate several expected totals before asking the agent to write code. Those examples then act as an independent oracle.
Generated tests tend to favour visible paths
An agent can quickly produce tests for ordinary input. Students should deliberately investigate:
- empty values;
- minimum and maximum boundaries;
- unexpected types and malformed data;
- duplicate operations;
- unauthorised users;
- partial network or database failure;
- retries after a timeout;
- large datasets;
- operations occurring in a different order;
- locale, time-zone and date-boundary behaviour.
Use several forms of checking
A stronger safety net combines:
- unit, integration and end-to-end tests where appropriate;
- static type checking;
- linting and formatting rules;
- security and dependency scanning;
- database constraints;
- code review;
- runtime logging and monitoring;
- manual checks against the original requirement.
None is sufficient alone. A linter enforces selected rules, not business correctness. A type checker can prevent many incompatible values, but cannot determine whether the correct student received the correct mark. A security scanner detects known patterns, not every missing authorisation decision.
Generated code has a maintenance cost
AI has made code cheap to produce. It has not made code free to own.
Every additional line may need to be read during debugging, adapted when a dependency changes and tested when another feature is introduced. An agent can create more code in ten minutes than a human reviewer can properly understand in an hour.
During a 2026 discussion about contributions to FFmpeg, VideoLAN president Jean-Baptiste Kempf explained that its core community was very small compared with the number of people who had contributed over time.
"We are the ones who are going to maintain your code." - Jean-Baptiste Kempf
This is particularly relevant to AI-generated pull requests. The person who produces a change may disappear after an assignment, internship or short contract. The remaining team must understand it when a bug appears two years later.
Common forms of agent-created technical debt
- several helpers that perform almost the same task;
- new abstractions that obscure a simple operation;
- business rules copied into several interfaces;
- inconsistent error-handling patterns;
- dependencies added for trivial functionality;
- comments that merely repeat the code;
- unused functions and abandoned experimental files;
- large configuration changes unrelated to the requested feature;
- tests coupled so tightly to the implementation that useful refactoring becomes difficult;
- different naming and architectural conventions in each generated feature.
Review the diff rather than admiring the result
After an agent completes a task, the student should be able to answer:
- Which files changed and why?
- Which behaviour existed before?
- Which public interfaces have changed?
- Were any dependencies or permissions added?
- Where are the new business rules located?
- Which tests would fail if the implementation were removed?
- Can the change be divided into smaller, reviewable units?
Cursor itself recommends small semantic commits because a single change containing hundreds of generated lines is difficult to review. The same principle applies to student work. Ask the agent to make one coherent change, inspect it, then continue.
Vibe coding is useful, but it is not a curriculum
In February 2025, AI researcher Andrej Karpathy coined the term vibe coding for a way of building software through conversational instructions while paying very little attention to the implementation.
"Forget that the code even exists." - Andrej Karpathy
The original description was playful and referred partly to throwaway weekend projects. The phrase was memorable because it captured a genuine change: somebody could describe what they wanted, run the result, report what looked wrong and repeat the process without writing much code manually.
That can be perfectly reasonable for:
- a disposable prototype;
- a personal script with no sensitive access;
- a visual demonstration;
- testing whether an idea is worth developing properly;
- an internal tool with limited consequences and reliable backups.
It is a poor default for:
- software handling money, health or personal information;
- a shared codebase that other people must maintain;
- infrastructure with production access;
- a security-sensitive system;
- an assessed programming task intended to demonstrate understanding;
- anything whose failure could materially harm another person.
A prototype can establish that an interface is useful without establishing that the generated implementation should be deployed. Students should learn to distinguish exploration from engineering.
What AI is genuinely good at
The case for learning syntax should not become an argument for banning useful tools. AI can remove a great deal of low-value friction from programming.
Boilerplate and repetitive transformations
Agents can generate routine data classes, serializers, test setup, configuration files and repetitive interface components. They can update a pattern across several files or translate a small implementation between languages.
The output still needs review, but manually typing repetitive structures is not the intellectual centre of computer science.
Explaining unfamiliar errors
A compiler error may assume knowledge a beginner does not yet possess. AI can restate it, identify the relevant lines and construct a smaller example. This can be more useful than pasting a complete replacement.
The student should ask what caused the error and how to recognise it next time, rather than requesting only a corrected file.
Generating testing ideas
AI is useful for brainstorming boundary values, invalid inputs and failure scenarios. It can inspect an existing test suite and identify visibly uncovered branches.
The student must still decide which behaviours are important and whether the generated expected results are correct.
Repository exploration
In an unfamiliar codebase, an agent can identify likely entry points, trace references and explain how several modules interact. This can reduce the time spent searching.
Its explanation should be checked against the actual files. A confident architectural summary can overlook dynamically loaded behaviour, configuration or conventions outside the retrieved context.
Small, verifiable refactoring
Renaming an interface, removing a deprecated API or converting a repeated operation into a shared helper can suit an agent particularly well when automated checks are strong and the intended transformation is precise.
The more subjective the architectural decision becomes, the more important human judgement becomes.
Comparing approaches
One of the best educational uses is to ask for alternatives rather than an answer. A student can request an iterative and recursive version, compare two data structures or examine the consequences of server-side and client-side validation.
AI becomes a source of material for analysis instead of a mechanism for avoiding it.
What research on students tells us
Research into AI-assisted programming education is still young. Studies use different tools, populations and tasks, and many samples are small. The emerging pattern is not that AI always harms or always improves learning. It is that students benefit differently depending on what they already understand and how they use the tool.
Completion can conceal an illusion of competence
A detailed observational study of 21 novice programmers found that 20 completed the assigned problem with access to generative AI tools. Students who progressed well tended to use AI to create code they had already intended to write and ignored incorrect or unhelpful suggestions.
Students who struggled experienced a different process. The tool could lead them through a sequence of apparently productive steps without correcting their underlying misunderstanding. Some finished believing they had performed better than researchers' observations suggested, creating what the authors called an illusion of competence.
The study was small and conducted at one site, so it should not be treated as a universal estimate. It illustrates a serious educational problem: a student can obtain a working output without becoming better able to solve the next problem.
Students can become faster without understanding more
A 2025 experiment involving ten undergraduate computer science students examined work on an unfamiliar legacy web application. With GitHub Copilot, students completed tasks 35% faster and made 50% more progress towards the solution.
They spent less time typing code and searching the web, but interviews raised concerns about not understanding how or why Copilot's suggestions worked.
A later study of 18 computer science graduate students similarly found that Copilot reduced task time and increased the number of tests passed, while comprehension scores did not significantly improve. The researchers described this as a comprehension–performance gap.
These are small studies, but they ask the right question. Producing more passing code is useful; it is not identical to developing a stronger model of the system.
Trust needs to be calibrated rather than maximised
Another study followed 71 upper-division computer science students during immediate and ten-day use of GitHub Copilot on a legacy codebase. Average trust increased as students saw the tool work and learnt more about how it used context.
After the project, students nevertheless emphasised that some tasks still required a competent programmer to verify or correct the output. The researchers recommended that computer science teaching retain traditional skills in comprehension, modification, debugging and testing so that students can create evidence for trusting a result.
Educators are already changing assessment
An ACM survey published in July 2026 received 763 responses from computing educators across 49 countries, with roughly 500 complete responses used in the main analysis. Sixty-nine per cent believed the skills required to create software had changed because of generative AI. Eighty-seven per cent identified increased dependency on AI as a concern, and more than two-thirds had changed their assessment practices.
The challenge is not to recreate 2019 by policing every autocomplete suggestion. It is to design work that reveals whether a student can understand, evaluate and improve software even when code generation is readily available.
What computer science students should still practise without AI
Students should use AI during some work because they are likely to encounter it professionally. They should also complete carefully selected tasks without it so that lecturers and students can see which knowledge has actually been internalised.
Writing common language constructs
Students should be able to write and modify ordinary variables, conditions, loops, functions, collections, modules and error handling without asking for every line. Constantly interrupting thought to obtain basic syntax makes it difficult to form a coherent model of the program.
Tracing execution
Given a short piece of code, a student should be able to predict:
- which branch executes;
- how many times a loop runs;
- which values change;
- what a function returns;
- which side effects occur;
- where an error will be raised;
- what asynchronous work remains unfinished.
This is the foundation of reviewing generated code.
Debugging from evidence
Students should practise reproducing an error, reducing it to a smaller case, inspecting state, forming a hypothesis and testing that hypothesis. Repeatedly pasting error messages into a chatbot can fix an immediate issue without teaching why it occurred.
Choosing data structures and algorithms
An AI tool can suggest a hash map, queue, graph traversal or sorting method. The student should know what properties make it suitable, how its cost changes with input size and which alternatives exist.
A program that returns the right answer on ten elements may still be unusable on ten million.
Working with other people's code
Professional software work is largely brownfield development: reading, changing and testing systems created by other people. Students need practice locating behaviour in a substantial repository, understanding conventions and making a narrow change without rewriting everything.
This also prevents the habit of asking an agent to regenerate a system each time an existing design becomes inconvenient.
Testing and specification
A student should be able to derive tests from requirements, recognise missing cases and explain what a successful test proves. The AI can help generate the mechanics after the student has identified the required properties.
Version control and code review
Students should understand branches, commits, diffs, merges and rollback. Agentic development makes this more important because large automated changes need safe checkpoints and a clear review history.
Basic security habits
Input validation, output encoding, authorisation, secret management, safe database access and dependency checking should become routine rather than optional requests added after an agent has finished.
The ACM and IEEE-CS curriculum guidance continues to include basic syntax and semantics, variables, data types, control structures, functions and recursion. It also emphasises program comprehension, correctness, specifications, secure coding, reviews, testing, refactoring and debugging. Syntax is presented as a foundation for those activities, not the final objective.
A practical way to use AI without outsourcing the learning
1. Check the academic rules
Establish what the module permits before using an agent. Rules may distinguish between explanation, autocomplete, debugging, test generation and submitting generated code. Keep any required record of prompts, outputs or declarations.
Permission in one module does not automatically carry into another.
2. Describe the behaviour before requesting the implementation
Write down:
- the users and their permissions;
- the valid inputs;
- the expected outputs;
- the rules that must always remain true;
- the failure behaviour;
- the expected volume and concurrency;
- the technologies and dependencies already approved.
For a booking system, an invariant might be: At most one confirmed booking may exist for the same room and overlapping time period, unless an authorised administrator records an override.
This is more useful than saying, Prevent double bookings.
3. Ask for a plan before code
Inspect the repository and propose two approaches. Do not edit any files yet. For each approach, identify the files affected, where the booking rule would live, how concurrency would be handled, which tests would be needed and what trade-offs it creates.
This exposes architectural choices before they are buried inside hundreds of changed lines.
4. Add explicit constraints
Use the project's existing validation and repository patterns. Do not add a new dependency without explaining why the existing tools are inadequate. Keep HTTP handling separate from booking policy and database operations. Ask before changing the schema.
Do not assume the agent will infer these requirements from what a good developer might normally do.
5. Make the change small enough to review
Ask for one coherent step: a database constraint, policy function, endpoint change or test set. Review it before proceeding.
A 20-file change may be appropriate eventually, but it should not arrive as an indivisible answer that the student cannot inspect.
6. Predict the behaviour before running it
Read the changed code and write down what should happen for several inputs. Then run the program or tests. A discrepancy between the prediction and result reveals a gap in understanding that would otherwise be hidden by a green test indicator.
7. Verify dependencies and APIs independently
Open the official documentation. Confirm that the package, method and option exist in the version used by the project. Check whether an apparently convenient API is deprecated or behaves differently under failure.
8. Test the requirement, not merely the implementation
Create boundary, permission, error and concurrency cases from the specification. Where possible, have somebody or something independent review the expected results.
9. Ask the agent to criticise the result
Review this diff as a sceptical maintainer. Look specifically for duplicated business rules, queries inside loops, missing authorisation, unbounded input, unsafe retries, unnecessary dependencies and tests that merely repeat the implementation.
This does not replace human review, but it changes the interaction from unconditional generation to adversarial examination.
10. Explain the finished system without the chat history
A student should be able to explain:
- the route taken through the program;
- where important state is stored;
- why the chosen data structure or architecture fits;
- which assumptions remain;
- how the tests establish correctness;
- what would need to change at a larger scale.
If the explanation depends on asking the agent again, the student does not yet own the solution.
Prompts that encourage better engineering
No prompt guarantees good code, but carefully stated constraints make accidental architectural choices less likely.
For an existing repository
Before changing anything, locate the existing pattern used for similar features. List the relevant files and explain the request flow. Make the smallest change consistent with that pattern, and do not create a parallel abstraction unless you can show why the existing one is unsuitable.
For separation of responsibilities
Keep domain rules independent of the web framework and database. The route should validate and translate the request, the use-case layer should apply the rule, and persistence should remain behind the existing repository interface. Explain any reason to depart from this structure.
For scalability
Assume the table may contain 500,000 rows and that 100 requests may arrive concurrently. Identify query count, memory use, transaction boundaries and any shared state. Do not optimise speculatively, but flag anything that would clearly fail at that scale.
For testing
Derive tests from the stated requirements rather than from the current implementation. Include exact boundaries, invalid data, permissions, duplicate requests and partial failure. Explain what each test proves and what it does not prove.
For review
Explain every changed file in one sentence. Identify any new dependency, public interface, database operation or permission. Highlight code you are least confident about and give a manual way to verify it.
When a real programmer is more useful than another AI response
An AI assistant can produce an immediate answer at any time. That speed is valuable, but another generated solution is not always what a struggling student needs.
A human programmer can observe how the student is thinking. They can ask why a particular data structure was chosen, discover that the student has misunderstood object references or explain why a proposed fix merely conceals the error. They can adapt the explanation to the course level and distinguish a useful simplification from an approach that will create trouble later.
A capable human reviewer can also challenge the brief itself. They may notice that the assignment requires use of a particular algorithm, prohibits a framework or expects evidence of testing rather than merely a working interface. A general-purpose agent may optimise for the visible outcome and miss what the assessment is actually intended to demonstrate.
Students who need support interpreting a programming brief, debugging their own implementation, separating responsibilities or reviewing AI-generated code may find specialist programming assignment help useful. The value of an experienced programmer is not simply another block of code. It is a reasoned explanation of why an approach fits the task, where it may fail, how it can be tested and what the student needs to understand before using it.
A human programmer can be wrong too. Students should still inspect the reasoning, ask questions and check the work against the module requirements. Any model solution or external support must be used within the university's academic-integrity rules rather than submitted as the student's own work.
A checklist before accepting AI-generated code
Understanding
- Can I explain what every changed function or module is responsible for?
- Can I trace a normal request from input to output?
- Can I predict what happens when an operation fails?
- Do I understand the unfamiliar language features used?
Requirements
- Does the implementation satisfy the actual wording of the brief?
- Which assumptions did the agent make because the specification was incomplete?
- Are important rules implemented in one authoritative place?
- Does any apparently convenient change conflict with an assessment requirement?
Structure
- Are interface, business and persistence concerns reasonably separated?
- Has similar logic been duplicated?
- Has the agent introduced an unnecessary abstraction or dependency?
- Does the change follow the project's existing conventions?
Correctness
- Have boundaries, invalid inputs and error paths been tested?
- Could two concurrent operations violate an important rule?
- Are the tests independent of the implementation's assumptions?
- Has the changed behaviour been checked manually against examples?
Performance
- Are network or database operations repeated inside a loop?
- Is a large or unbounded collection loaded into memory?
- Are requests needlessly serial or dangerously unlimited in parallel?
- What happens when the dataset becomes ten or one hundred times larger?
Security
- Are authentication and authorisation enforced on the server?
- Is user-controlled input safely handled?
- Are secrets excluded from the repository?
- Do all packages exist and come from credible maintainers?
- Does the agent have more environmental access than the task requires?
Maintenance
- Is the diff small enough for meaningful review?
- Could another developer identify where to change the behaviour later?
- Are comments explaining reasons rather than repeating the code?
- Can the feature be removed or replaced without rewriting unrelated parts?
Academic integrity
- Was this form of AI assistance permitted?
- Have any required declarations or prompt records been completed?
- Could I reproduce or modify the core idea during a discussion or practical assessment?
- Does the submitted work demonstrate my own understanding?
What syntax should a graduate know from memory?
The precise answer varies by language and specialism, but a computer science graduate should normally be comfortable with:
- variables, values and types;
- expressions and operators;
- conditionals and loops;
- functions, arguments, return values and scope;
- collections and common data structures;
- modules, imports and interfaces;
- errors, exceptions and resource cleanup;
- references, mutation and object lifetime;
- file, network or database input and output;
- the language's main asynchronous or concurrency model;
- basic testing constructs;
- the build and dependency process used by the project.
They should also be able to recognise constructs they do not routinely write and locate authoritative documentation for the details.
They do not need to memorise every library method, framework option, compiler flag or deployment file. Professional competence is not measured by whether somebody can recreate an entire application with no documentation. It is measured partly by whether they know what must be checked and can recognise when an answer is implausible.
The answer is yes, but the reason has changed
Computer science students still need to learn syntax. They do not need to compete with an AI system at producing boilerplate or recalling obscure APIs. They need enough fluency to read generated programs, reason about their behaviour and remain in control when the first plausible solution is not the right one.
AI changes the balance of programming work. Less time may be spent typing ordinary structures. More time can be spent defining requirements, comparing designs, reviewing changes, constructing tests and investigating failures. That is progress only when the student possesses the foundations needed to perform those activities properly.
The scarcity in software development is no longer code that looks convincing. Coding agents can produce that in enormous quantities. The scarce abilities are judgement, verification, architectural consistency, security awareness and willingness to reject a solution that works today but creates an expensive problem tomorrow.
A student should therefore learn enough syntax to read, edit, predict, test and reject code without asking the same tool that wrote it whether it is correct. AI can then become a genuine accelerator rather than a machine for concealing what the student has not yet learnt.
Sources and further reading
- GitHub Copilot features and student access
- OpenAI Codex
- Claude Code documentation
- Cursor documentation
- Cursor, reviewing and testing AI-generated code
- Replit Agent documentation
- Google Jules
- JetBrains Junie documentation
- Kiro
- Peng and colleagues, GitHub Copilot productivity experiment
- Paradis and colleagues, Google developer productivity trial
- METR, early-2025 open-source developer productivity study
- METR, 2026 developer-productivity experiment update
- Stack Overflow Developer Survey 2025, AI section
- Spracklen and colleagues, package hallucinations in code-generating models
- Perry and colleagues, security outcomes with AI coding assistance
- Amjad Masad's response to the Replit production-database incident
- Andrej Karpathy's original description of vibe coding
- Jean-Baptiste Kempf and Kieran Kunhya on FFmpeg and maintainability
- Prather and colleagues, benefits and harms of generative AI for novice programmers
- Shihab and colleagues, Copilot use in undergraduate brownfield programming
- Qiao and colleagues, the comprehension–performance gap in AI-assisted programming
- Shah and colleagues, computer science students' trust in programming assistants
- ACM survey of generative AI and programming assessment
- ACM and IEEE-CS software development fundamentals curriculum guidance