Thursday, 5 November 2026

Chapter 2 — Twelve Fifty-One



The cockpit again.

He knew it better than the room he rented. A fine scratch crossed the glass at the upper left of the instrument panel, as if someone had tested it with a fingernail. Half the lights in the third row stayed dark, the other half left unused on purpose. A shallow cut marked the leather on the right armrest. He knew every mark. This was not an old machine. The cockpit was newer, quieter, smarter than anything he had seen in Kestra. He had simply known it for longer than he had known any landlord in his building. Since he was six.

Every time he entered the dream, he did the same check. Left hand on the frame. Right hand over the three marks: scratch, half-lit row, shallow cut. A sentry making his rounds. There was no time in the dream, but he always felt the machine waiting for him to finish the count.

No sound. There had never been a voice in this dream. The machine was there. His hands knew it. Everything else was dark, and the dark had all the patience in the world.

He woke before the alarm.

A strip of blue-grey showed between the curtains. He watched the ceiling for three seconds, then reached for his phone. Two lunch orders, booked in advance: 12:10 and 12:51. He took both. He never turned down a pre-booked run. One rejection could shave half a point off his on-time score, and these were regulars. Same addresses every time; they barely bothered with notes. He liked those orders.

He needed to be at the prep counter by 12:44 for the later one. Seven minutes was the margin. Any earlier and the food would not be ready; any later and the bag sat waiting too long on the rack.

The bed frame creaked as he got up. The room woke with him. In this rented place, only two things made noise: the bed frame and Lucan.

He washed, pulled on his riding clothes, wound the charging cable twice and tucked it into the side pocket of his bag. He tapped the dust from his helmet lining. Before leaving, he looked back into the room. There was nothing to see. He looked anyway.

Too much riding, he told himself. Every morning, the same excuse for the dream. He never changed the wording.

At 6:12 he rode up onto the pavement and slipped past a garbage truck stuck at the light. He knew this stretch without looking. One ring of the bell and people moved. Dogs, too.

Kestra in the morning was a city at knee height. Cabbages rose to a market seller's waist. Fish flashed in the tanks. Steam from the breakfast stalls slid along the tiles. Lucan cut through the middle without using his horn. The bell was enough. Horns were for people who did not know the road.

He had ridden this street a hundred times. Vera had probably walked it as often, he thought. Speed changed what you saw. She might notice the stalls and the sky; he looked for a gap wide enough to pass through, a loose paving stone that would kick his back wheel sideways, a kitchen door that let out soup at half past six. He had delivered to that shop so often he could tell how many portions were in the pot by the smell.

He liked the market just after it opened. Every stall smelled like breakfast, even if he usually had to ride on before he could eat any. He kept a breakfast ranking: pepper broth at the corner, first; fried dough two stalls down, second. On a rare day off, he'd try something new and see if it could beat the broth. No app could rate breakfast. The broth led by half a point, though he was open to appeals.

He rarely looked up. Riders did not watch the sky; people who watched it had time to spare. He caught the freight shuttles and their fading trails in the corner of his eye, the same things he imagined Vera saw when she looked up.

A ball rolled into his path. The child came after it. Lucan braked, put one foot down and waited until the kid had the ball before riding on. The first lesson this job taught him was not how to find an address. It was to stop half a beat before everyone else.

The shortcut ran beneath a covered arcade. Air-conditioning units dripped overhead; the paving stayed damp all year. The old man who watched the far end lifted one eyelid when Lucan passed. That counted as a greeting. The cut-through saved two minutes. Two minutes meant money.

Rent in five days. He ran yesterday's take: the platform's cut, a battery swap, the visor he still had not replaced. Its crack climbed from the lower left like lightning frozen in ice. Through it, every red light looked doubled. He had tested it; he followed the one on the right. The money home stayed the same. His family had never asked if it was enough; he had never said it wasn't. He put his phone away and took the next order.

At 12:44 he opened the insulated carrier and touched the rack. Dry.

He checked it every time. Other riders glanced and moved on. Lucan thought the note "don't spill the drink" had been written for a day exactly like this. A pipe leaked every winter and had stained the wall black on the left end of the rack. He was the only courier who checked the dry corner before setting down a bag.

He had noticed the leak last winter while sheltering from the rain. Vera had been there too, cursing the pipe: "Every year." She had not been talking to him. He remembered the words anyway. Since then, checking that corner had become his craft. He could do it more reliably than the app could keep time.

He folded a napkin twice and slid it under the sauce cup. The cup sat secure in its holder. Her tea: light ice. Months ago, she had mentioned it once to the room, as if talking to the air. He happened to hear and remembered the two words.

Then the chili sachet.

He took one from the little compartment and folded it into the napkin. Months ago, while waiting at the workshop counter for a signature, he had heard her say to the room, "I want something spicy." Her wrench kept moving. She never ordered chili herself. Maybe she'd felt awkward once she'd said it out loud. So he slipped a sachet into her bag. He had never told her.

The food was ready. He sealed the bag and stuck the label on.

The name at the top was VERA P., his LUCAN underneath. Her eyes passed over his name as if it were a phone number. He told himself he was used to it.

At the door, he set the bag down on all four corners.

She did not look up. "Leave it there, thanks."

In that half-second, he almost said her name. Vera. He had practised it once inside his helmet and never tried again. He had made himself a rule: if she ever looked up at him first, he would say it. She never had.

The handle of his insulated carrier pressed a groove into his palm. The app would record the delivery time. The pause had lasted half a second; turning away took him two full seconds. He imagined she had measured it too. He had no proof.

The delivery door closed behind him with a chime. He left the half-second inside, as if nothing had happened.

He never waited for the lift. He never changed an address or invented a reason to come by the workshop. When the app sent him one of her orders, he worked the rest of his route around it. He left the bag at the door and went.

At lunch, the riders gathered in their usual place and compared ratings. One customer had left him three stars with the note: "Soup spilled." It had been sealed. He had checked it; the photo on his phone showed it intact, the shot steady. He did not appeal. Uploading it, filling out a form and waiting for someone he would never meet to decide was time he could not spare.

The new kid had a 4.99. Lucan said, "Four point nine eight."

"You care about a hundredth?"

"It's the closest thing I've got to a promotion."

Someone told him to take airport runs. The fares were better.

"Not on my route," Lucan said.

"Your home isn't near the airport either."

"No. Home's not on the way to the airport."

The answer came quicker than thought. He had rehearsed it for a different kind of detour, one only he knew about.

At three, the workshop's coffee order came through. The foreman ordered the same thing every day: black, no sugar. Lucan had made this delivery often enough to know where to park and where the foreman wanted the cup. Hydraulic oil, then coffee.

The shutter was half open. He parked beyond the yellow line, carried the coffee inside and checked the whiteboard. The foreman tipped his head toward the table. Lucan put the cup in its usual corner. He had done it so many times he could have cut a key by feel.

Then he saw her.

She stood in the middle of the floor.

The room was full of noise: the compressor, a pneumatic wrench, the grinder farther back, someone's music, a mechanic at station three swearing at a bolt that would not catch. But she was listening to something else. Her head tilted. Her shoulders lifted a little. Lucan knew the look. It was what a person did when she lent her whole body to her ears.

He stopped and counted to five. One, two, three, four, five.

He heard nothing.

He could list every sound in the room: the compressor in two long bursts and a short one; the wrench in threes; the song reaching its chorus again; the mechanic changing his curse after the third word. Four sounds. Nothing more. He did not know what the fifth one was. He only knew that she had heard it, and that for him, the four were everything.

Maybe the floor really was making a noise. When he reached five, all he could hear was the workshop. Not one sound more, not one less. At the door, a new kid called out, "Heard it again? Your floor." Vera ignored him. The others turned back with grins.

The new kid saw Lucan and raised his chin. "You think she really hears something?"

Lucan lifted the coffee. "I hear you lot making a racket."

He finished the handoff without laughing or joining in. They had made enough jokes about her already. He had stood in the same place for five seconds and heard nothing; at least this time, he had not laughed along.

Back on his bike, the seat was still hot from the afternoon sun. He did not start the engine right away. He looked once at the shutter. Was she still standing in the middle of the floor? He did not know. He only knew his own ears had been empty for five seconds, and that he had stood there for nothing.

His last run before seven was to the hospital. The night nurse took the bag and thanked him. Her eyes were red. He did not ask why. A rider's rule: other people's red eyes were not his business.

Outside the hospital doors, the wind tugged his collar open. Only then did he realize he had been holding his breath.

His last delivery was after dark.

He took the covered arcade shortcut. The air-conditioning units that dripped all day had gone quiet. In the alley he could hear only his tires crossing the damp paving. Halfway through, he squeezed the brake.

A beetle clung to the wall.

Not an ordinary one. It was as big as a crouching person. Its wing cases were folded tight, all six legs hooked into the gaps between the bricks. It was as black as the alley. If he had not ridden this cut-through every day, if he did not know each brick by sight, it might have been part of the wall.

He slowed to half speed.

Halloween prop, he thought. Those were popular this year, the kind that crawled up walls. The hardware shop had a row of them outside. Their eyes lit up, too.

He rode on.

Twenty metres past it, a chill reached the back of his neck. He could not have said what was wrong. He tugged his collar higher and repeated Halloween to himself. Right. Halloween.

His front wheel bumped over a tile at the mouth of the alley. He did not look back.

That night, the cockpit again.

He knew where every instrument sat. He lifted his hand, and the fine scratch waited under his fingertip. He had dreamed this cockpit for nearly twenty years. Since six: machine there, hands knowing, no voices, not a word. Once he had fallen asleep gripping a wrench, trying to bring something into the dream with him. He woke with the wrench under his pillow. Nothing had followed him in.

When he was six, he told an adult about the dream. Children had strange dreams, they said. He stopped bringing it up, but the dream stayed with him for twenty years.

He had waited for the cockpit to change. A light coming on would have been enough. A seat turning a few degrees. Nothing ever did. He had nearly got used to that.

Tonight was different.

Before he reached for it, the control stick moved.

Only two inches, toward him. No sound. Nothing in that dream made a sound, which made the movement plain as a mark scratched into the dark. He started to reach. Before his hand moved, the stick shifted another half-inch, as if it knew.

Not a fault. A test. Something asking: Are you still there?

He woke with his hand raised, fingers spread, reaching into empty air.

The room was exactly as he had left it. The charging cable in his bag. His helmet on the stool. Nothing moved. Nothing could explain that two-and-a-half-inch shift. He checked his phone: 2:47. Tomorrow's orders were already lining up.

Kestra outside the curtain was black as a sheet. He lay still for a while, then lowered his hand to the blanket. The dream did not come back. It never worked overtime.

He turned his palm over and studied it. There was nothing in the lines of it, but the weight of that two-and-a-half-inch shift was still there, like something he had carried a long way and did not dare set down.

Too much riding, he told himself again. He did not believe it either.

The two and a half inches stayed in his palm. He rolled onto his side and closed his hand around them.

Chapter 1 — The Word at 4 A.M.




The cockpit knew her hands.

Every switch on the console was a shape she had never seen before, and her fingers went there anyway. Thumb to the ignition plate. Two fingers to the trim wheel. Palm flat on the smooth panel where no seam showed. Pale light filled the canopy, the color of deep sky a breath after the sun leaves it, and the stick settled into her grip as if it had been poured there.

She ran the preflight out of order, the way she always did in the dream, and the console agreed with every wrong step. Somewhere outside the canopy a voice said something patient and unfinished, the way a person keeps talking to a machine that is already listening.

4:07. The dream let go.

Vera lay in the bed she had grown up in, in the apartment her grandmother had left her three streets from the old quarter, and listened. The floor was humming again. Ducts? The neighbor's compressor? Or an old quarter settling in the night, because old quarters do that. Three good explanations, none of them worth chasing once she was awake.

She had been six the first time, in this same room, listening to a floor that never stopped working. The cockpit never changed, and her hands never forgot it. She rolled over and named the hum to herself (geothermal line, definitely the geothermal line).

The movement woke him, or gave him the excuse he always used.

"Still flying?" Cassius murmured, without opening his eyes.

He remembered. Three months ago she had come out of one of those dreams and told him the whole impossible thing, switches she had never seen and hands that knew them anyway, and he had listened the way he listened to the stories that cost him nothing, and asked about it ever since. It was possibly the only thing he remembered about her shifts, her floor, her.

Something in her unclenched. She turned to him, found his mouth in the dark, and the kiss he gave back was still half asleep: warm, unhurried, certain of where it was going, the way everything with Cassius began.

What followed had the shape everything with him had: he was certain first. His hand went under her shirt and traveled the line of her ribs, the way a man traces a blueprint he owns. She felt his mouth on her jaw, her throat, and last the hollow behind her ear, where one touch could break a sentence in half, and his other hand pinned her hip to the mattress she had grown up on. The shirt came off over her head and the dark took it somewhere. His skin was already warm, already faintly damp, and he was in no hurry except about breathing, which he did against her collarbone until her body answered first and her mind followed willingly.

She had always liked this about him: wanting showed up in his whole body, openly, with nothing kept back for later. He went after what he wanted wholeheartedly, cheerfully, and for himself. Clothes were a problem solved and then not a problem. His weight settled over her, solid and deliberate, a man who filled the whole room around her, and when he started to ask whether she wanted him to stop, she pulled him down by the shoulder and answered the question with her mouth.

He laughed once, low, and the laugh broke into a gasp where she moved under him. The bed, old and opinionated about weight, began to creak in a rhythm it had never learned from her alone, and under it the floor kept up its own low hum, and neither sound had anything to say to the other. Her hands went down his back and counted nothing. His mouth found the underside of her jaw and stayed there, and every time she stopped thinking, the cockpit loosened its grip on her fingers by one more.

Past talking, past the point where either of them would have bothered with words, the rhythm narrowed into a thing with no language in it. Faster now. Her breaths broke into smaller pieces; his stayed even. The peak came through them both like a door swinging on one hinge, all at once and in one direction, and after that she was gone to a place the cockpit had never once let her into.

He was asleep in under a minute, arm thrown across her waist like a claim staked. Cassius could sleep the way he did everything: instantly, and without apology. She lay listening to his breathing stacked over the floor's low hum, one hum on top of the other, and felt the old room settle around them. Her right hand lay open on the sheet, curled around nothing, still holding a stick that existed nowhere in this city.

Six forty, alarm. The city had been awake for two hours without her.

Kestra woke on time, as it did every morning. At 6:42 the first cargo shuttle crossed the river, its contrails over the hangars. On the market road, the patrol machine walked its route past the fish vendors, a house on legs, its joints too quiet to rattle the crates. A kid on a stack of boxes waved. The machine raised a hand half a beat late, as always. Nobody looked up from their cabbages.

Vera's walk to work took six minutes. She knew the route's cracks: the step that iced first, the courier who mounted the curb, the old woman who fed pigeons and had never learned Vera's name.

She had walked this route at every hour. Six in the morning was her favorite: the city with its collar down, belonging to nobody. At twenty-five, she had a handsome trader at home who called her grease-stained mechanic work a cute phase. If that counted as a life, the cabbages still had to be moved.

Four minutes off the clock, at the market crossing, a small van went sideways into a cabbage truck and the lane closed like a fist. Nobody was hurt; the cabbages had lost. Vera swore, checked the time, and went around the long way. The bay never noticed her late. The bay never noticed much.

Morning in the bay: work orders, radiator, coffee that tasted like the log book. The foreman did not look up from his screen. "Model agency called. They want their face back."

"Tell them I'm booked till retirement."

Her face had got her free coffees and extra scrutiny for as long as she could count, and she had stopped keeping score. In the dark window over the filing cabinets she saw herself: pretty face, harder mouth, and the mouth was the part that settled things.

Unit Six had been up on its stand since yesterday, a knock nobody could place, three men arguing hydraulics over lunch like men at a racetrack. She let them spend their coffee, put her ear against the hip actuator, and had the loose panel bolted in nine minutes: the same nine minutes the day shift had spent agreeing the fault was intermittent.

Someone told her another week of days, and her request to swap to nights got the same "not yet". The pilot course had been a "not yet" for three years running, and the not-yet always wore the same warm face: the force trains its own, the academy keeps the list, the bay is where you are useful. She was useful. The word sat in her like a bolt that looks seated and isn't.

Past the roller door, a patrol machine went by on its way to nothing in particular, and she watched it longer than she needed to.

On her break she did the thing she never mentioned: climbed into Unit Two's dead cockpit, hands on sticks she could rebuild blindfolded, and sat through lunch while the bay ate around her. The ignition was wired to her badge, and her badge said mechanic. So she sat, and the machine offered exactly what it offered everyone: nothing. Since she was six, she had dreamed of this. The cockpit in her sleep was always kinder.

12:51, her phone lit up with the lunch run.

The bag hit the rack by the door with a knock she could have picked out of any noise in the building. She was on the third rewrite of a work order about a patrol machine that had put its knee through a shopfront, fault or pilot error being the disputed part.

"Leave it there, thanks."

She did not look up. She never looked up, she realized around the fourth month of never looking up.

The rack's left end stayed dark from the pipe that leaked every winter. The bag sat on the dry corner, as it always did, never the wet side. The drink carrier was wedged so nothing could tip it, a napkin folded under the sauce cup so the cup could not slide on the walk over. Her tea, light ice, once said out loud to the room, months ago, in the middle of three other sentences, to nobody.

The order line on the bag read VERA P., and under it the courier's name: LUCAN, read the way people read phone numbers: straight through, kept for nobody. She tapped delivered and went back to the work order.

There was a chili sachet again. She had not ordered chili since the day she mentioned wanting some over her shoulder at the counter, a perfectly normal thing to say to thin air, and saying it out loud made ordering it feel too obvious. Since then the sachet arrived folded under the napkin every time, square and red and unexplained.

The delivery door chimed shut behind him. Half a second later, she noticed the half second: there was always one at the end of the delivery, a pause where whoever it was stood like a man about to say something, in a job where nobody ever said anything, because the app had already said it. Rain, she told herself. Weather. She had a work order to fix, and by the time she looked at the door, the door was only a door.

Nineteen hundred, shift over. She did not go home.

She sat in with the night crew: machines were going with the contractors to clear the salvage lane tonight or not at all, and somebody had to listen to them work. Half for the paperwork. Half because the apartment hummed louder than the bay, and at least here the hum had coffee.

Twenty-one hundred, a drunk on the pier and his fishing photos. Twenty-two forty, the vending machine and the rookie's playlist. She was into the night log when the radio came alive at 00:40. Shelving collapse, wholesale market, no injuries reported, two hundred kilos of canned goods across the delivery lane.

Unit Four was already rolling. Its cabin smelled of vinyl and the coffee of three previous shifts, and the seat had been worn into somebody else's shape. The operator had eleven years on the machine and none of them interested him, and he walked it down the empty avenue in long flat strides that made the streetlights sway.

Inside the wholesale market, the machine's arm put a pallet of cans two inches from a wall and held it there while the crew kicked crates in underneath. The night crew treated it as furniture that happened to move. Nobody looked up at Unit Four the way the kid looked up at the morning patrol, because at three in the morning nobody looked up at anything.

From the second seat, every movement the machine made looked effortless, which was exactly what the dream felt like and what she could not have while awake.

In the dream, she flies something nobody ever showed her, and her hands know things her head never learned, and the machine answers before she finishes wanting it to. Here she watched another man's hands fight a grip that fought back, in a cabin that smelled of other people's shifts, and the machine was a good machine, a municipal machine, and it was the wrong machine in every direction. It had weight, it had noise, it argued. The dream did not argue. The dream agreed with her about everything, and she had never once been able to bring a single detail of it out into the light.

A foreman walked beside her with a clipboard, spending the whole walk on how this would cost him his bonus and must go on the record that he had reported it. She let him spend it all: a man who has just lost his bonus will sign anything, provided you let him finish the sentence first. Eleven seconds. The lane opened by 01:20.

Back at the bay at 02:30, the break room had tea going and the floor doing it again.

It was a low thing, below hearing, more felt than heard: knees first, teeth second. She tilted her ear without meaning to, and the juniors pounced: heard it again? Her floor. The old crew no longer took the bait, the way people stop taking up an old joke.

"So your floor was singing again?" the rookie needled. "My grandmother swore the same thing: the old quarter sings, like it's proud of something."

"Vents," said the old mechanic, not looking up from his log book.

"Rent," the rookie said. "So old, even the floor's got a landlord."

Then the rookie leaned in. Three weeks on the job, still pleased to be awake at this hour. "You want the real one? The Blue God."

"Older than the city, maybe older than the war. Sleeping under the oldest streets, blue as deep sky." He stopped for a drink. Nobody hurried him.

"Priests went down to wake it and came back empty-handed. Mayors, too. A monument stands downtown, but no one knows when it was erected. Engineers drilled nine hundred meters. The bit came back coated in blue dust. No geologist would sign the report."

"Every telling ends the same way: it doesn't hate you. It hasn't woken, and it won't wake for you."

"It isn't angry," the rookie finished. "It just doesn't answer. That's almost worse."

"Every bit that ever bit old rock comes back blue," the old mechanic said. "Page four of every report I filed. If there's a god down there, it owes me rent."

They turned with grins, the way rooms do when a question travels. "Vera. You grew up three streets from the old quarter. Did the floor ever sing to you?"

"Heard it plenty." She set her cup down. "Never got an answer either."

The room went back to its tea. Nobody asked her what she meant, which she preferred, and which was also, she thought, the only riddle she had ever solved about this city: people stopped asking exactly one question short of the answer.

Three ten, she walked home.

Sodium lamps on wet asphalt. The patrol machine standing dark at the junction, off duty, hands empty, looking smaller without anyone watching it. Stars thinning toward morning. Her own steps, her own breath, years of nights in a city that never thanked her for staying up.

The apartment key, the kitchen light, the same three steps from the door to the counter. And there on the tile: a cockroach, big as a thumbnail, dark as a freshly minted coin. She raised her foot.

It did not run. It turned to face her and held, a half beat past the point where insects hold anything, the way a listening thing holds.

Her stomp found bare tile. Under the stove, most likely, already. The light, the hour, twelve hours of shift. She told herself she had simply missed, and did not find the thought as comforting as she meant it to be.

She put the kettle on. The tea went cold beside her. She did not remember getting into bed. Sleep came down like a thrown switch.

Cockpit. Pale light. And now the voice, patient as before, spoke in the Old Tongue, the language every child here grew up understanding without ever being taught. It came through the canopy padding from everywhere at once, still saying its unfinished thing. She understood it the way you understand your own name called from another room: not translating, just knowing, and reaching.

Then the voice put all its weight on a single word, once, like a stamp pressed into the center of her chest.

Corath.

4:07.

Vera lay with her eyes open. The bed beside her rose and fell on Cassius's breathing, unbroken. The word sat inside her. She had simply never turned around to look at it. She did not know it. She had never heard it. It was not in any language she had studied or any prayer she had been taught, and it did not feel foreign, and that was worse. Foreign she could have thrown out.

She got up and stood at the sink for no reason she would have admitted to. Over the sink, the window stood open two fingers wide to the night. Vesper hung low above the roofline. Everyone called it the evening star, and at four in the morning it had no business still being up.

There it was anyway, keeping hours nobody had taught it.

Behind her, on the floor of the kitchen, nothing hummed. Or rather, something did, and she had run out of explanations that were worth the trouble of saying out loud.

Monday, 17 January 2022

Difference between "docker stop" and "docker kill"

 To stop a running container, you can use either "docker stop" or "docker kill" command to do so. Although it seems doing the same thing, actually there is a slight difference between them.

"docker stop" command will send a hardware signal SIGTERM to the container, if the process received the SIGTERM signal, the developer can code to do some clean up and releasing some resources before terminating the process.

However "docker kill" command will send a hardware signal SIGKILL to the container and stop it immediately.

Usually "docker stop" is used to stop a running container. If the container is hanging there for a long time or failed to stop. Then you can try to use "docker kill"to kill the container anyway.

Sunday, 26 December 2021

Why do we need an accordant pace in computer systems

In the past, we always know clock is used to adjust the pace of the computer systems. But we don't understand why we need an accordant pace in computer systems. Why don't we just let the components in the computer do as much and fast as they can?

The reason is that the different components have dependency between each other. So if we image the whole computer systems is a succession program, of course we don't need accordant pace any more. But this will make the components in computer wait for each other's result to go on. So this can't make components work in parallel way.

So obviously clock has this advantage which is that it can make different components work in parallel way become possible.

Sunday, 28 November 2021

DO NOT use the return of append function to create new slice in Go

For Golang developers, it is very common to use append function to append new elements into slice. The common syntax is like below:

    var slice := make([]int, 0)
    slice = append(slice, 123)
And for some requirements, you may want to create a new slice based on an existing slice. We know the below the code will work perfectly.
    slice := []int{1,2,3}
    newSlice := make([]int, 0)
    newSlice = append(newSlice, append(slice, 4)...)
Below is complete example code to show the result:
package main

import (
    "fmt"
)

func main() {
    // here create the origin slice with cap 10 to make sure that
    // the slice is big enough to hold more data
    slice := make([]int, 0, 10)
    slice = append(slice, []int{1, 2, 3}...)
    newSlice := make([]int, 0)
    newSlice = append(newSlice, append(slice, 4)...)
    fmt.Println(slice)
    fmt.Println(newSlice)
    fmt.Printf("The address of slice: %v\n", &slice[0])
    fmt.Printf("The address of newSlice: %v\n", &newSlice[0])
}
The result is:
[1 2 3]
[1 2 3 4]
The address of slice: 0xc000014050
The address of newSlice: 0xc00007a000
You can see the two slices have different addresses.
However you may think if we can simplify the code by appending value to the origin slice and assign the return value to the newSlice variable like below:
    slice := []int{1,2,3}
    newSlice := make([]int, 0)
    newSlice = append(slice, 4)
This looks simpler and cleaner, right? NO, this won't work! Let's see an example:
package main

import (
    "fmt"
)

func main() {
    // here create the origin slice with cap 10 to make sure that
    // the slice is big enough to hold more data
    slice := make([]int, 0, 10)
    slice = append(slice, []int{1, 2, 3}...)
    newSlice := make([]int, 0)
    newSlice = append(slice, 4)
    fmt.Println(slice)
    fmt.Println(newSlice)
    fmt.Printf("The address of slice: %v\n", &slice[0])
    fmt.Printf("The address of newSlice: %v\n", &newSlice[0])
}
The result is:
[1 2 3]
[1 2 3 4]
The address of slice: 0xc00010a000
The address of newSlice: 0xc00010a000
See newSlice is pointing to the same address of slice?

This is because append function does not guarantee that it always returns a new slice. It only reallocate a new slice when the capacity of the slice in the first parameter is not enough to hold more data. So if you are expecting to use append function to get a new slice like above, you will probably mess up the origin slice and get the wrong output.
So to be safe, if you want to get a new slice based on an existing slice, you use the code below:
    slice := []int{1,2,3}
    newSlice := make([]int, 0)
    newSlice = append(newSlice, append(slice, 4)...)
Or below code if it is clearer.
    slice := []int{1,2,3}
    newSlice := make([]int, 0)
    newSlice = append(newSlice, slice...)
    newSlice = append(newSlice, 4)
I encountered this problem when I am practicing LeetCode problem 797. 



Wednesday, 17 November 2021

How to add optional arguments in Go function without impacting the existing function calls

Unlike C# you can put "Optional" keyword to add optional arguments in function, there is no direct way to create optional parameters in Go functions. And there is no method overloading in Go either. Even so, if you really need to add optional arguments to an existing function, maybe because this function is in a common library which is called by different software modules and you don't want to update all the modules for this new argument change, there is still a way to implement optional arguments thanks to variadic arguments in Go functions.

Variadic arguments allow developer to put any number of trailing arguments as the input of functions. For example:

package main

import (
  "fmt"
)

func main() {
  fmt.Printf("1 + 2 = %d\n", add(1, 2))
  fmt.Printf("1 + 2 + 3 + 4 + 5 = %d\n", add(1, 2, 3, 4, 5))
}

func add(args ...int) int {
  sum := 0
  for i:=0; i < len(args); i++ {
    sum += args[i]
  }
  return sum
}
The output is:
1 + 2 = 3
1 + 2 + 3 + 4 + 5 = 15
With the help of variadic arguments, you can easily to implement optional arguments. For example, you have a function to generate characters in a common library for a game development. This function can generate characters with name and sex for now. 
package main

import (
  "fmt"
)

func main() {
  createCharactor("Bertram", "Male")
}

func createCharactor(name string, sex string) {
  fmt.Println("---------- New Charactor ----------")
  fmt.Printf("Name is: %s\n", name)
  fmt.Printf("Sex is: %s\n", sex)
  fmt.Println("------ New Charactor Created ------")
}
The output is: 
---------- New Charactor ----------
Name is: Bertram
Sex is: Male
------ New Charactor Created ------
Now you want to add age argument to this function without impacting the existing function call. You can do like following:
package main

import (
  "fmt"
)

func main() {
  createCharactor("Bertram", "Male")
  fmt.Println()
  createCharactor("Kai", "Male", 15)
}

func createCharactor(name string, sex string, age ...int) {
  fmt.Println("---------- New Charactor ----------")
  fmt.Printf("Name is: %s\n", name)
  fmt.Printf("Sex is: %s\n", sex)
  if len(age) > 0 {
    fmt.Printf("Age is: %d\n", age[0])
  }
  fmt.Println("------ New Charactor Created ------")
}
The output is:
---------- New Charactor ----------
Name is: Bertram
Sex is: Male
------ New Charactor Created ------

---------- New Charactor ----------
Name is: Kai
Sex is: Male
Age is: 15
------ New Charactor Created ------
But the above code is not reusable to add other arguments with different data types. For example, what if you need to add title, email later? So in order to make the variadic argument more generic, we can use "interface{}" type as the variadic argument which gives the ability to add more arguments with different data types.

According to this, the above code can be refactored as below:
package main

import (
  "fmt"
)

func main() {
  createCharactor("Bertram", "Male")
  fmt.Println()
  createCharactor("Kai", "Male", 15, "Software Engineer", "kai@gmail.com")
  fmt.Println()
	
}

func createCharactor(name string, sex string, args ...interface{}) {
  fmt.Println("---------- New Charactor ----------")
  fmt.Printf("Name is: %s\n", name)
  fmt.Printf("Sex is: %s\n", sex)
  if len(args) > 0 {
    fmt.Printf("Age is: %d\n", args[0].(int))
    fmt.Printf("Tile is: %s\n", args[1].(string))
    fmt.Printf("Email is: %s\n", args[2].(string))
  }
  fmt.Println("------ New Charactor Created ------")
}
The output is:
---------- New Charactor ----------
Name is: Bertram
Sex is: Male
------ New Charactor Created ------

---------- New Charactor ----------
Name is: Kai
Sex is: Male
Age is: 15
Tile is: Software Engineer
Email is: kai@gmail.com
------ New Charactor Created ------

However, this solution does not convey the meaning of the optional arguments. So you either put a comment above the header to specify what it means for each optional argument, or comment where you call the functions, otherwise it will become very difficult to understand the code. So this solution is not recommended unless you have a very tight deadline to meet the delivery date and really have no time to refactor code.  

Sunday, 24 October 2021

Pointer Receiver vs Value Receiver

Receivers are same as parameters in function in Go. They are also passed by value when functions are called. Because of this, it is preferred to use pointers as receivers instead of passing values directly. This is because usually we use receivers to implement OOP programming style. If passed by value, the properties of the objects will not be able to update.

For example, we have an object called "person", it has age property. Initially when created, the person has initialised the age to 0, then we use method to change it to 18. See code below:

package main

import (
	"fmt"
)

type Person struct {
	Name string
	Age int
}

func main() {
	person := Person{Name : "Leo"}
	fmt.Println(person)
	person.SetAge(18)
	fmt.Println(person)
	
}

func (p *Person) SetAge(age int) {
	p.Age = age
}
The output of the result is:
{Leo 0}
{Leo 18}
However if the receiver is passed by value like below:

func (p Person) SetAge(age int) {
	p.Age = age
}

Then the age property will not be updated. However if the receiver is passed by value like below:

{Leo 0}
{Leo 0}

Chapter 2 — Twelve Fifty-One

The cockpit again. He knew it better than the room he rented. A fine scratch crossed the glass at the upper left of the instrument panel, as...