Header image

Xử Lý Lỗi Theo Phong Cách Lập Trình Hàm Trong Kotlin Với Arrow-kt

07/04/2022

1.28k

Xử Lý Lỗi Theo Phong Cách Lập Trình Hàm Trong Kotlin Với Arrow-kt

Bài viết này sẽ giới thiệu một số cách để xử lý lỗi trong Kotlin theo phong cách lập trình hàm sử dụng thư viện Arrow-kt. Những ví dụ được đưa ra sẽ theo thứ tự từ đơn giản đến phức tạp nhưng mạnh mẽ hơn.

Kotlin là gì?

Kotlin là một ngôn ngữ lập trình kiểu tĩnh, ban đầu được thiết kế để chạy trên máy ảo Java (JVM), sau này có thể biên dịch sang JavaScript và Native binaries sử dụng công nghệ LLVM. Kotlin có cú pháp hiện đại, ngắn gọn, an toàn và hỗ trợ cả lập trình hướng đối tượng (OOP)lập trình hàm (FP).

Arrow-kt là gì?

Arrow-kt (https://arrow-kt.io/) là một thư viện Typed Functional Programming trong Kotlin. Arrow cung cấp một ngôn ngữ chung của các interface và sự trừu tượng hóa trên các thư viện Kotlin. Nó bao gồm các kiểu dữ liệu phổ biến nhất như Option, Either, Validated, v.v … và các functional operator như traversecomputation blocks giúp cho người dùng viết các ứng dụng và thư viện pure FP dễ dàng hơn.

Setup

Trong file build.gradle.kts của root project, thêm mavenCentral vào danh sách:

allprojects {
    repositories {
        mavenCentral()
    }
}

Thêm dependency vào file build.gradle.kts của project:

val arrow_version = "1.0.1"
dependencies {
    implementation("io.arrow-kt:arrow-core:$arrow_version")
}

Pure function và exceptions

Pure function

Trong lập trình hàm, pure function là những function có hai tính chất:

  • Giá trị trả về chỉ phụ thuộc vào tham số truyền vào nó (tức là nếu cùng input thì cùng output).
  • Không tạo ra các side effect.

Side effect là những tác dụng xảy ra khi thực hiện một function mà không phải công dụng chính của nó. Ví dụ: ngoài việc trả về các giá trị, nó gây ra những tương tác thay đổi môi trường, thay đổi các biến toàn cục, thực hiện các hoạt động I/O như HTTP request, in dữ liệu ra console, đọc và ghi files Trong Kotlin, tất cả các function trả về Unit rất có thể tạo ra side effect. Đó là bởi vì giá trị trả về là Unit biểu thị “không có giá trị hữu ích được trả về”, điều này ngụ ý rằng function không làm gì khác ngoài việc thực hiện các side effect.

Một số ví dụ pure function trong Kotlin là những hàm toán học như sin, cos, max, …

Lợi ích của pure functions: dễ dàng combine, dễ dàng test, dễ dàng debug, dễ dàng parallelize, … Vì thế trong lập trình hàm, chúng ta sẽ cố gắng sử dụng nhiều pure functions nhất có thể, và tách biệt các phần pure và impure.

Exceptions

Kotlin có thể throwcatch các Exception tương tự như ngôn ngữ Java, JavaScript, C++,… Sử dụngtry { } catch(e) { } finally { } là cách xử lý lỗi phổ biến trong các ngôn ngữ lập trình mệnh lệnh.

Tuy nhiên việc throw và catch các Exception, chúng ta có thể thay đổi hành vi của function, khiến cho các function không còn pure nữa (catch Exception là một side effect). Ví dụ, một function catch hai Exception là ex1ex2 từ một function khác và tính toán kết quả, lúc đó kết quả đó sẽ phụ thuộc vào thứ tự thực thi của các câu lệnh, thậm chí có thể thay đổi giữa hai lần thực thi khác nhau của cùng một hệ thống.

Partial function

Ngoài ra, việc throw các Exception khiến cho các function trở thành một Partial function, tức là một function không hoàn toàn – không được xác định cho tất cả các giá trị input có thể có, bởi vì trong một số trường hợp, nó có thể không bao giờ trả về bất cứ thứ gì. Ví dụ, trong trường hợp một vòng lặp vô hạn hoặc nếu một Exception được throw.

Ví dụ: findUserById ở ví dụ dưới là một partial function.

@JvmInline
value class UserId(val value: String)

@JvmInline
value class Username(val value: String)

@JvmInline
value class PostId(val value: String)

data class User(
    val id: UserId,
    val username: Username,
    val postIds: List<PostId>
)

class UserException(message: String?, cause: Throwable?) : Exception(message, cause)

/**
 * @return an [User] if found or `null` otherwise.
 * @throws UserException if there is any error (eg. database error, connection error, ...)
 */
suspend fun findUserById(id: UserId): User? = TODO()

Đề làm cho findUserById trở thành một total function, chúng ta thay vì throw UserException, chúng ta có thể return nó như một giá trị, thay return type của findUserById thành UserResult.

sealed interface UserResult {
    data class Success(val user: User?) : UserResult
    data class Failure(val error: UserException) : UserResult
}

suspend fun findUserById(id: UserId): UserResult = TODO()

Các vấn đề với Exceptions

Exception có thể được xem như là những câu lệnh GOTO như trong C/C++, vì chúng làm gián đoạn luồng chương trình bằng cách quay lại nơi gọi nó. Các Exception không nhất quán, đặc biệt là khi trong lập trình Multithread, chúngta try...catch một function nhưng Exception được throw ở một Thread khác mà không thể catch nó được.

Một vấn đề khác là việc lạm dụng catch Exception: catch nhiều hơn những gì cần thiết và cả những Exception từ hệ thống như VirtualMachineError, OutOfMemoryError,…

try {
    doExceptionalStuff() //throws IllegalArgumentException
} catch (e: Throwable) {
    // too broad, `Throwable` matches a set of fatal exceptions and errors
    // a user may be unable to recover from:
    /*
    VirtualMachineError
    OutOfMemoryError
    ThreadDeath
    LinkageError
    InterruptedException
    ControlThrowable
    NotImplementedError
    */
}

Và cuối cùng, nhìn vào một signature của một function, chúng ta không thể biết được, nó sẽ throw ra Exception nào, ngoài việc đọc docs hay là đọc source code của nó, thay vào đó, chúng ta hay để signature của function đó biểu hiện rõ ràng những lỗi nào có thể xảy ra khi gọi function đó.

Vì vậy, để xử lý lỗi, chúng ta cần một type có thể được compose với nhau, và biểu thị một kết quả hợp lệ hoặc một lỗi. Những type đó là Discriminated union/ tagged union, trong Kotlin đó được triển khai thông qua sealed class/sealed interface/enum class. Chúng ta sẽ cùng tìm hiểu kotlin.Result được cung cấp bởi Kotlin Sdtlib từ version 1.3 , và sau đó là arrow.core.Either đến từ thư viện Arrow-kt.

Sử dụng kotlin.Result để xử lý lỗi

Chúng ta có thể sử dụng Result<T> như là một type để biểu thị: hoặc là giá trị thành công với type là T, hoặc là là một lỗi xảy ra với một một Throwable. Nếu theo cách hiểu đơn giản, Result<T> = T | Throwable.

Để tạo ra giá trị Result, ta có thể dụng các function có sẵn như

  • Result.success
  • Result.failure
  • runCatching (tương tự như try { } catch { }
    nhưng trả về Result).
suspend fun findUserByIdFromDb(id: String): UserDb? = TODO()

fun UserDb.toUser(): User = TODO()

suspend fun findUserById(id: UserId): Result<User?> = runCatching { findUserByIdFromDb(id.value)?.toUser() }

Chúng ta có thể kiểm tra Result là giá trị thành công hay không, thông qua hai property là isSuccessisFailure. Để thực hiện các hành động ứng với mỗi trường hợp của Result thông qua function onSuccessonFailure.

val userResult: Result<User?> = findUserById(UserId("#id"))
userResult.isSuccess
userResult.isFailure
userResult.onSuccess { u: User? -> println(u) }
userResult.onFailure { e: Throwable -> println(e) }

Để có thể lấy giá trị bên trong Result, chúng ta sử dụng các function getOr__. Sử dụng exceptionOrNull để truy cập giá trị Throwable bên trong nếu Result đại diện cho giá trị thất bại. Ngoài ra, còn có function fold có thể handle một trong hai case dễ dàng.

val userResult: Result<User?> = findUserById(UserId("#id"))

// Access value
userResult.getOrNull()
userResult.getOrThrow()
userResult.getOrDefault(defaultValue)
userResult.getOrElse { e: Throwable -> defaultValue(e) }

// Access Throwable
userResult.exceptionOrNull()

fun handleUser(u: User?) {}
fun handleError(e: Throwable) {
    when (e) {
        is UserException -> {
            // handle UserException
        }
        else -> {
            // handle other cases
        }
    }
}

userResult.fold(
    onSuccess = { handleUser(it) },
    onFailure = { handleError(it) }
)

Tuy nhiên, sức mạnh thực sự của Result nằm ở việc chain các hoạt động trên nó. Ví dụ: nếu bạn muốn truy cập một property của User:

val userResult: Result<User?> = findUserById(UserId("#id"))
val usernameNullableResult: Result<Username?> = userResult.map { it?.username }

Chú ý rằng, nếu việc gọi lambda truyền vào function map throw Exception, thì Exception đó sẽ bị throw ra ngoài. Nếu muốn Exception đó được catch và chuyển thành giá trị Result, sử dụng mapCatching để vừa map vừa catching.

val usernameResult: Result<Username> = userResult.map {
    checkNotNull(it?.username) { "user is null!" }
}

Một vấn đề đặt ra là làm sao để chain các Result mà phụ thuộc lẫn nhau

// (UserId) -> Result<User?>
suspend fun findUserById(id: UserId): Result<User?> = TODO()

// User -> List<Post>
suspend fun getPostsByUser(user: User): Result<List<Post>> = TODO()

// List<Post> -> Result<Unit>
suspend fun doSomethingWithPosts(posts: List<Post>): Result<Unit> = TODO()

Chúng ta tạo một function flatMap (mapflatten).

// Map and flatten
inline fun <T, R> Result<T>.flatMap(transform: (T) -> Result<R>): Result<R> = mapCatching { transform(it).getOrThrow() }

// or
inline fun <T, R> Result<T>.flatMap(transform: (T) -> Result<R>): Result<R> = map(transform).flatten()
inline fun <T> Result<Result<T>>.flatten(): Result<T> = getOrElse { Result.failure(it) }

Bằng việc sử dụng flatMap, chúng ta có thể chain các Result với nhau

val unitResult: Result<Unit> = findUserById(UserId("#id"))
    .flatMap { user: User? -> runCatching { checkNotNull(user) { "user is null!" } } }
    .flatMap { getPostsByUser(it) }
    .flatMap { doSomethingWithPosts(it) }

Thư viện Arrow-kt cũng cung cấp block result { ... } để có thể handle việc chain các Result với nhau, tránh một số trường hợp sử dụng quá nhiều các nested flatMap. Trong block result { ... }, sử dụng function bind() để lấy giá trị T từ Result<T>. Nếu bind được gọi trên một Result đại diện một lỗi, thì phần code ở phía dưới nó trong block result { ... } sẽ bị bỏ qua (cơ chế short-circuits).

import arrow.core.*

val unitResult: Result<Unit> = result { /*this: ResultEffect*/
    val userNullable: User? = findUserById(UserId("#id")).bind()
    val user: User = checkNotNull(userNullable) { "user is null!" }
    val posts: List<Post> = getPostsByUser(user).bind()
    doSomethingWithPosts(posts).bind()
}

Một số tình huống khác có thể yêu cầu các chiến lược xử lý lỗi phức tạp có thể bao gồm khôi phục hoặc báo cáo lỗi. Ví dụ, chúng ta fetch data từ remote server, nếu bị lỗi thì sẽ lấy data từ cache. Chúng ta có thể sử dụng 2 function recoverrecoverCatching,

class MyData(...)

fun getFromRemote(): MyData = TODO()
fun getFromCache(): MyData = TODO()

val result: Result<MyData> = runCatching { getFromRemote() }
    .recoverCatching { e: Throwable ->
        logger.error(e, "getFromRemote")
        getFromCache()
    }

Sử dụng Result là một cách tiếp cận này tốt hơn, tuy nhiên vấn đề là lỗi luôn luôn là một Throwable, ta phải đọc docs hoặc đọc source code của nó. Một vấn đề nữa là runCatching khi kết hợp với suspend function, nó sẽ catch mọi Throwable, kể cả kotlinx.coroutines.CancellationException, CancellationException là một Exception đặc biệt, được coroutines sử dụng để đảm bảo cơ chế cooperative cancellation (xem issues 1814 Kotlin/kotlinx.coroutines).

Một cách tiếp cận tốt hơn là sử dụng arrow.core.Either, khắc phục các nhược điểm của Result.

Sử dụng arrow.core.Either để xử lý lỗi

Chúng ta có thể sử dụng Either<L, R> như là một type để biểu thị: hoặc là giá trị Left(value: L) , hoặc là giá trị Right(value: R). Nếu theo cách hiểu đơn giản, Either<L, R> = L | R.

public sealed class Either<out A, out B> {
    public data class Left<out A> constructor(val value: A) : Either<A, Nothing>()
    public data class Right<out B> constructor(val value: B) : Either<Nothing, B>()
}

Trong đó, Left thường đại diện cho các giá trị lỗi, giá trị không mong muốn, và Right thường đại diện cho các giá trị thành công, giá trị mong muốn. Nhìn chung Either<L, R> tương tự với Result<T>, Result<T> chỉ tập trung vào type của giá trị thành công mà không quan tâm đến type của giá trị lỗi, và chúng ta có thể xem Result<R> ~= Either<Throwable, R>. Eitherright-biased, tức là các function như map, filter, flatMap, … sẽ theo nhánh Right, nhánh Left bị bỏ qua (được return trực tiếp mà không có hành động nào trên nó cả).

Để tạo ra giá trị Either, ta có thể dụng các function có sẵn như:

  • Left constructor, ví dụ: val e: Either<Int, Nothing> = Left(1)
  • Right constructor, ví dụ: val e: Either<Nothing, Int> = Right(1)
  • left extension function, ví dụ val e: Either<Int, Nothing> = 1.left().
  • right extension function, ví dụ val e: Either<Nothing, Int> = 1.right().
  • Either.catch functions, catch các Exceptions nhưng nó sẽ bỏ qua các fatal Exception
    như kotlinx.coroutines.CancellationException, VirtualMachineError, OutOfMemoryError,…
  • Và nhiều cách được cung cấp bởi arrow.core.Either.Companion.
suspend fun findUserByIdFromDb(id: String): UserDb? = TODO()

fun UserDb.toUser(): User = TODO()

fun Throwable.toUserException(): UserException = TODO()

suspend fun findUserById(id: UserId): Either<UserException, User?> =
    Either
        .catch { findUserByIdFromDb(id.value)?.toUser() } // Either<Throwable, User?>
        .mapLeft { it.toUserException() }                 // Either<UserException, User?>

Chúng ta có thể kiểm tra Either là giá trị Left hay Right, thông qua hai function là isLeft()isLeft(). Either cũng cung cấp hai function tap (tương tự onSucesscủa Result) và tapLeft (tương tự onFailure của Result).

val result: Either<UserException, User?> = findUserById(UserId("#id"))
result.isLeft()
result.isRight()
result.tap { u: User? -> println(u) }
result.tapLeft { e: UserException -> println(e) }

Tương tự như Result, chúng ta sử dụng các function getOrElse, orNull, getOrHandle để lấy giá trị mà Right chứa nếu nó là Right. Một số function hữu ích nữa là fold, bimap, mapError, filter,…

val result: Either<UserException, User?> = findUserById(UserId("#id"))

// Access value
result.getOrElse { defaultValue }
result.orNull()
result.getOrHandle { e: UserException -> defaultValue(e) }

fun handleUser(u: User?) {}
fun handleError(e: UserException) {
    // handle UserException
}

result.fold(
    ifRight = { handleUser(it) },
    ifLeft = { handleError(it) }
)

Tương tự ví dụ khi sử dụng Result, chúng ta cũng muốn chain nhiều giá trị Either với nhau

// (UserId) -> Either<UserException, User?>
suspend fun findUserById(id: UserId): Either<UserException, User?> = TODO()

// User -> Either<UserException, List<Post>>
suspend fun getPostsByUser(user: User): Either<UserException, List<Post>> = TODO()

// List<Post> -> Either<UserException, Unit>
suspend fun doSomethingWithPosts(posts: List<Post>): Either<UserException, Unit> = TODO()

Thư viện Arrow-kt đã cung cấp sẵn function flatMap và block either { ... } để có thể chain các Either với nhau dễ dàng. Trong either { ... } block, sử dụng function bind() để lấy giá trị R từ Either<L, R>. Nếu bind được gọi trên một Either chứa giá trị Left, thì phần code ở phía dưới nó trong block either { ... } sẽ bị bỏ qua (cơ chế short-circuits).

import arrow.core.*

class UserNotFoundException() : UserException("User is null", null)

val result: Either<UserException, Unit> = findUserById(UserId("#id"))
    .flatMap { user: User? ->
        if (user == null) UserNotFoundException().left()
        else user.right()
    }
    .flatMap { getPostsByUser(it) }
    .flatMap { doSomethingWithPosts(it) }

// or either block

val result: Either<UserException, Unit> = either { /*this: EitherEffect*/
    val userNullable: User? = findUserById(UserId("#id")).bind()
    val user: User = ensureNotNull(userNullable) { UserNotFoundException() }
    val posts: List<Post> = getPostsByUser(user).bind()
    doSomethingWithPosts(posts).bind()
}

Cuối cùng là cách khôi phục lỗi. Tương tự như recoverrecoverCatching của Result, chúng ta có thể sử dụng hai function handleErrorhandleErrorWith (giống như flatMap nhưng theo nhánh Left).

class MyData(...)

suspend fun getFromRemote(): MyData = TODO()
suspend fun getFromCache(): MyData = TODO()

val result: Either<Throwable, MyData> =
    Either
        .catch { getFromRemote() }
        .handleErrorWith { e: Throwable ->
            Either.catch {
                logger.error(e, "getFromRemote")
                getFromCache()
            }
        }

Kết luận

Chúng ta đã cùng tìm hiểu Result và sau đó là Either, cả hai type giúp xử lý lỗi và làm giảm side effect. Either còn chỉ rõ về những lỗi có thể xảy ra mà chỉ cần nhìn vào signature của một function. Ngoài ra, Either hỗ trợ cho suspend function mà không làm mất đi cơ chế cancellation, và Arrow-kt cũng có module Fx (https://arrow-kt.io/docs/fx/) giúp cho việc sử dụng Kotlin Coroutines dễ dàng hơn, khi viết các chương trình asyncconcurrent.

Hy vọng bạn thích bài viết này và hôm nay bạn đã học được điều gì đó hữu ích!

Tài liệu tham khảo

  • Arrow-kt – Either docs
  • Arrow-kt – Error handlding
  • Arrow-kt – Monad comprehension
  • Ciocîrlan, D. (2021) Idiomatic error handling in scala, Rock the JVM Blog. Available at: https://blog.rockthejvm.com/idiomatic-error-handling-in-scala/ (Accessed: 04 October 2024).

Author: st-hocnguyen

Related Blog

recap Hackathon AI-driven event of SupremeTech

Our culture

+0

    SupremeTech’s AI Hackathon 2025: A blend of Product-Focused Spirit and AI-assisted Development

    On September 6–7 of 2025, we hosted our very first AI-Driven Development Hackathon. Ten teams, all made up of SupremeTech members, stepped out of their daily routines to take on real business challenges. Within just 22 hours, they brainstormed, coded, and pitched solutions showcasing their creative application of AI-powered tools. This Hackathon was more than a competition. It was an opportunity for SupremeTech’s members to experiment with AI in practical ways, strengthen their teamwork, and grow into product builders in the AI era. And, of course, they get themselves a chance to win VND 100,000,000 in prize money. Real business challenges from retail & tourism industries Before jumping into the final pitches of 10 teams, let’s take a look at the challenges that will later inspire their creativity. Some of them are quite familiar topics, while others might be a bit more challenging and out-of-the-box.  As CEO Mr. Bình explained: “When shaping the problem statement, I wanted to balance three things. First, it had to be close enough to our real business so that outcomes could have practical value. Second, it needed to challenge teams to apply AI meaningfully not just add AI as a decoration, but use it to create efficiency or new capability. And third, it should be simple and open enough so that everyone, regardless of role, could participate and learn something from the process.” Though this Hackathon centers the theme of “AI-Driven Development”, each challenge was designed to be: Close to real business needs so that outcomes could have practical applicationsAI-driven, but in a practical and meaningful way, to create efficiency or new capabilitiesOpen enough for all roles to participate, learn, and contribute Now, let’s dive into the details of each challenge.  Omnichannel E-Commerce & Loyalty App for Retail Brands This is one of SupremeTech’s current areas of expertise and key services. By including it as a challenge topic, teams worked on solutions that are highly applicable to existing clients, directly supporting our clients’ business growth.  For participants who face this challenge, it could be both a blessing and a curse. We’ve been building and managing a variety of EC and loyalty systems for clients. But when it comes to building a new one using AI, replicating the past experience may not be a smart choice. Judges, for sure, would want to see some real enhancements in the development process empowered by AI, not to mention the creativity in the strategic approach to this very familiar topic.  The original statement requires teams to develop an application that solves the problem of disconnected retail experiences. The solution should unify online and offline shopping while deeply integrating loyalty programs and personalization.  There could be a huge number of variations coming up from this statement. Stay tuned for the highlight performance!  Destination and Experience Management System for Tourism Managing group travel is a complex task often disturbed by miscommunication and inefficiencies. In a tourism hub like Da Nang, where businesses host frequent tours and events for a very large group of travelers, the ability to streamline logistics and improve participant engagement directly impacts customer satisfaction.  For companies, such apps not only reduce operational headaches but also enhance the overall brand experience they deliver. It can even drive sales if well structured and managed. In this statement, teams are required to develop a platform that streamlines group trip management. The solution should enable organizers to coordinate transportation, schedules, and interactions in one place, instead of relying on scattered tools like messenger apps.  The topic reflects SupremeTech’s own company trip pain points and has strong application potential for Da Nang’s tourism and hospitality businesses. Talent & Performance Management System for HR Apart from two industries above, in the third problem statement, we aimed to tackle the challenges of every human-driven company like ourselves.   When it comes to an integrated platform that not only tracks performance but also supports continuous growth and recognition, there’s very few choices.  This statement requires teams to develop an application that solves the problem of fragmented performance management. The solution should integrate goal setting, performance tracking, continuous feedback, and talent development into a single platform, helping organizations build a transparent culture where employees are recognized and aligned with business goals. How teams build the product is as important as the product itself Just as important as what teams built was how they built it. The Hackathon wasn’t only about coming up with clever ideas, it was about proving that execution, process, and teamwork are just as critical as the final product.  Many teams leaned on AI not just as a tool but as a true co-pilot: using AI-assisted frameworks to prototype faster, automating repetitive tasks, automating testing, and finding smarter ways to accelerate Agile development. What stood out was how teams adapted their workflows to make the most of AI. Some rethought their sprint planning with AI-driven insights. Others applied AI models to cut down on development cycles. And many discovered new ways to collaborate more effectively by letting AI handle the heavy lifting.  The Hackathon turned into a live experiment in how AI can reshape the way we build software. Creativity isn’t just in the idea itself, but in the entire journey of bringing it to life. Perspectives from the leaders and the participants From leadership: The Hackathon aligned employees with real client challenges, ensuring that innovation can directly contribute to business value. It proved that AI can be embedded into everyday problem-solving, not just theoretical projects. As Vice President Mr. Vĩ shared: “AI has already been selectively applied in SupremeTech’s real projects, depending on client expectations and suitability. In many cases, it helps optimize software production costs and shorten time-to-market. Through this Hackathon, I hope to spread the AI-assist mindset to a larger part of the company, so that AI gradually becomes embedded across all projects: enhancing efficiency, improving quality, and ultimately bringing benefits to both clients and the company. This year’s Hackathon focuses more on unlocking internal strength and setting a direction for the future. If everything goes according to plan, we will publish AI-assisted development as a new service offering. It is a clear statement that AI is being strategically applied at SupremeTech to deliver tangible value to our clients.” From participants: The challenge statements sparked two different but equally positive reactions.  Some teams loved how practical and relevant they were by mirroring the real projects we handle at SupremeTech. This gave them the perfect chance to not only test AI-assisted development but also to build solutions that might one day become our next official product. On the other hand, many appreciated how broad the challenges were. It leaves space for bold ideas and limitless creativity. With that freedom, participants could push boundaries, think like product owners, and imagine possibilities beyond the usual project scope. Conclusion The SupremeTech AI Hackathon 2025 proved to be more than an internal competition. From a business perspective: Participants gained experience and insights that sharpened their ability to think with a business mindset, ensuring their solutions were tied to real market needs. From a technical perspective: The event introduced an AI-assisted development process and innovative frameworks that can be applied immediately in client projects. By turning challenges into opportunities, the Hackathon reinforced SupremeTech’s positioning as a future-ready partner, capable of combining innovation, culture, and technical excellence to deliver AI-driven value to clients.

    10/09/2025

    96

    Quy Huynh

    Our culture

    +0

      SupremeTech’s AI Hackathon 2025: A blend of Product-Focused Spirit and AI-assisted Development

      10/09/2025

      96

      Quy Huynh

      Hackathon AI SupremeTech 2025

      Our culture

      +0

        A to Z about SupremeTech’s AI Hackathon 2025: Why We Do It and What to Expect

        This September 6–7, SupremeTech will host its first AI-Driven Development Hackathon, a landmark event designed to inspire teams to embrace artificial intelligence as a core part of how we work, innovate, and grow. The Hackathon is not just a competition. It is a statement of SupremeTech’s belief that learning and innovation are the backbone of both personal and organizational growth. Through this event, our engineers and product teams will have the opportunity to experiment, challenge themselves, and use AI to reimagine the way they work. By fostering creativity and adaptability, the Hackathon aims to enhance work efficiency today while leading the way for AI-assisted development as a core strength of our future. Why Hackathon Matters Now There are several ways companies may choose to approach and apply AI in their working process: training, workshop,… For SupremeTech we want to inspire our developers with a fun blend of innovative and competitive experiences. Hackathon is exactly the format we’re looking for. They compress ideation, experimentation, and execution into an intensive timeframe, creating an environment where bold ideas can quickly turn into actionable solutions. Furthermore, the high pressure of time would foster teamwork, collaboration and bonding to the next level. At SupremeTech, the AI Hackathon 2025 will serve as: A safe space to test AI ideas from concept to execution.A platform to help employees step out of their comfort zones and practice product-building skills.An accelerator of cross-functional teamwork, where developers, designers, and product leaders work together with AI as a co-pilot.A signal to clients and partners that SupremeTech is forward-looking, innovation-driven, and committed to AI adoption. SupremeTech AI Hackathon 2025 Overview Message & Objective:To raise awareness of the importance of continuous learning, growth, and self-breakthrough, enabling each individual to move forward together in collective progress. Format:The main theme of this Hackathon is “AI-Driven Development” focusing on how teams can utilize AI tools to build solutions and solve real-world problems.  Teams will have 22 hours to complete their challenge, followed by a 30-minute demo and pitching session to the judges. Results will be announced after the competition. Evaluation Criteria:Projects will be assessed across four dimensions: Business Value: Market fit, feasibility, economic efficiency, and contribution to SupremeTech’s brand.Engineering Quality: Coding standards, scalability, maintainability, security, and UI/UX design.Technical Execution: Completion of core features, testing outcomes, innovative use of AI tools, and potential for future expansion.Presentation & Pitching: Clarity of communication, demo quality, time management, team passion, and user experience. Main Business Domains Covered: The Hackathon challenges will center on the Retail sector, with a strong emphasis on Omnichannel and Luxury Retail Businesses. Within this domain, teams will explore AI-driven solutions in three key areas: Customer ExperienceMobile OrderingCustomer Data What Leaders Think About This AI Hackathon To provide insight into the vision behind the Hackathon, we spoke with its three leaders of SupremeTech, who directly run this initiative: Mr. Bình (CEO), Mr. Vĩ (Vice President), and Mr. Đào (CTO). Mr. Bình, CEO of SupremeTech “2025 is a turning point for us, a second-time startup for SupremeTech. The industry is moving very fast with AI, and I want our people to be at the front line of this change, not just following behind.” For Mr. Bình, the Hackathon is about more than prototypes. It is about building a culture where innovation and continuous learning are second nature. He hopes the event will give SupremeTech members the awareness that AI is not some distant future, but a tool they can apply today to enhance their work. To clients and partners, the Hackathon demonstrates that SupremeTech is serious about innovation and ready to bring AI-driven value into real projects. Mr. Vĩ, Vice President of SupremeTech From his perspective, the Hackathon plays a strategic role in long-term talent development. “Hopefully, through this AI hackathon, we will contribute to spreading the AI-assist mindset to a large number of company members, thereby popularizing AI in all projects at SupremeTech. In order to improve efficiency and quality, optimize costs to bring benefits to customers and the company.” He expects to see teams not only moving fast but also integrating AI across the entire development process. Beyond internal growth, the Hackathon sends a message to clients: SupremeTech is building a strategic roadmap for AI-assisted development that will optimize costs, shorten delivery time, and raise product quality. Mr. Đào, CTO of SupremeTech When judging, Mr. Đào will look for a balance between creativity and practical application. Both, he believes, are equally important. “The role of developers will not change much, but their skills will. Engineers will need to level up, becoming more capable as they learn to work alongside AI.” For him, the Hackathon represents a chance for teams to explore while ensuring their ideas can translate into real-world impact. >>> Read more related articles: How a Hackathon Changed My Life – A Personal Story from the CEO of SupremeTechHow Could You Join a Hackathon Without Knowing This? Our Developers Are Preparing for D-Day As the countdown to September 6 approaches, excitement is building across SupremeTech. Teams are forming, ideas are being exchanged, and strategies are taking shape. For our developers, this Hackathon is more than just a challenge, it is a chance to step outside their comfort zones, test their skills under pressure. Stay Tuned for Our Upcoming Updates The SupremeTech AI Hackathon 2025 is the beginning of a larger journey. It is about preparing people to work smarter with AI, strengthening a culture of innovation, and ultimately shaping the future of AI-assisted development in SupremeTech and beyond. By creating this space for learning and experimentation, SupremeTech is reaffirming its commitment to being both a reliable partner today and a forward-looking innovator tomorrow. 📩 Read more articles about us here: https://www.supremetech.vn/blog/

        05/09/2025

        111

        Quy Huynh

        Our culture

        +0

          A to Z about SupremeTech’s AI Hackathon 2025: Why We Do It and What to Expect

          05/09/2025

          111

          Quy Huynh

          When Technology Meets a Pioneering Spirit

          Our culture

          +0

            When Technology Meets a Pioneering Spirit

            SupremeTech’s Hackathon 2025 is not just a coding competition, it’s a place where bold ideas are tested, limits are broken, and new connections are formed. Every team carries its own story – about why they joined, their role in the group, or what they expect to gain after this intense yet inspiring journey. Among them, we had the chance to chat with Quang Dũng, a Technical Leader at SupremeTech, who is participating in a Hackathon for the very first time – while also taking on the role of team leader. Usually busy with deadlines and lines of code, this Hackathon is his opportunity to step away from routine work and challenge himself in a completely different way. We listened to his thoughts on challenges, pioneering spirit, and what he hopes to take away from this event. Let’s join SupremeTech and Quang Dũng in this conversation about the Hackathon! Q&A with Quang Dũng 1. Is this your first time joining a Hackathon?Yes, this is my first Hackathon. Everything feels new: the intensity, the pressure, and how teamwork changes under strict time limits. I wanted to experience this firsthand and compare it with the usual way of running projects. 2. What made you decide to sign up for the event?I wanted to challenge myself – to see how far I can go applying AI in real-world work. This is an opportunity for me and my team to pioneer ways of leveraging AI Copilot in a small group project of 3–5 people, while learning new workflows and testing practical applications. And of course, the prizes are also very attractive – hard to resist! Who knows, maybe I can go home and tell my wife that just two days of Hackathon brought back 50 million VND! (laughs). 3. What is your role in the team? If given the choice, what field would you like your project to be applied to?I’m the team leader – responsible for planning, setting the initial direction, and building a sample demo so everyone has a clear vision. In other words, I set the rhythm so the whole team can work smoothly together. If I had the chance to choose a project topic, I’d want it applied to practical areas like booking/reservation systems or internal management tools such as resource and project management. These fields are highly relevant to business needs and can create immediate value. 4. If you had to describe SupremeTech’s AI Hackathon in three words, what would they be? Challenge – Pioneer – Connection. Challenge: because everyone here must push beyond their own limits.Pioneer: because we are applying the latest AI technologies to real-world problems.Connection: connecting people, ideas, and the future of technology. 5. What do you expect to gain from this Hackathon? In my daily work, I’m often involved in project estimation. I expect this event will help me learn how to integrate AI Copilot into product development workflows. That could make estimations more accurate, save time, and improve overall efficiency at the company. In other words, what I look forward to most is not just the prize, but the knowledge and experience that can truly be applied to work. >> Read related articles: How a Hackathon Changed My Life – A Personal Story from the CEO of SupremeTech Closing SupremeTech’s Hackathon is more than a tech playground, it’s an opportunity for each individual to test themselves, learn, and break past their own limits. Stay tuned for the next tech journeys at SupremeTech, where even the smallest ideas can spark big changes!

            22/08/2025

            231

            Our culture

            +0

              When Technology Meets a Pioneering Spirit

              22/08/2025

              231

              tips when joining AI Hackathon

              Knowledge

              +0

                How Could You Join a Hackathon Without Knowing This?

                In the ever-evolving world of programming, the emergence of intelligent support tools is changing the way we write code. Copilot, often described as “AI-powered Pair Programming”, promises to revolutionize the workflow of software developers. In this article, I’ll focus on GitHub Copilot, the AI tool I personally use every day when coding. What is GitHub Copilot? GitHub Copilot is an AI assistant integrated into IDEs (VS Code, IntelliJ IDEA/PyCharm, Neovim) developed by GitHub and OpenAI. It provides context-aware code suggestions as you type, and includes Copilot Chat for Q&A directly inside the IDE. Key Advantages of GitHub Copilot Faster coding: Reduce time spent on repetitive tasks with context-aware suggestions (functions, code blocks, basic tests).Learn new technologies quickly: Get API/syntax examples directly in your IDE; ask further via Copilot Chat.Automate boring work: Scaffold endpoints, write boilerplate, create sample tests, suggest snippets, and ensure consistent formatting.Seamless IDE integration: Works in VS Code, JetBrains, Neovim; suggestions appear as ghost text/inline as you type. Limitations to Keep in Mind Not always accurate: May generate syntax, logic, or performance errors.Solution: Always review, run lint/tests, and benchmark when needed.Security & copyright risks: Could resemble public code or leak if sensitive data is pasted.Solution: Enable “block suggestions matching public code,” avoid entering secrets, follow organizational policies.Risk of dependency: Over-reliance may weaken fundamental coding skills.Solution: Use Copilot for speed, but keep code reviews and tests.Limited domain knowledge: Suggestions may not fit specific business contexts.Solution: Break down requests, add examples/constraints, manually refine critical parts. Quick Start (VS Code) Install extensions: GitHub Copilot and (optional) GitHub Copilot Chat.Log in to GitHub and enable suggestions in Settings.Create a new file, describe requirements in Vietnamese/English within comments or docstrings.Press Tab to accept, Esc to skip. Check IDE shortcuts for more. Simple Examples Just comment your request, and GitHub Copilot will write code for you. Example 1: Utility function to validate email (JavaScript) // Write function isValidEmail(email: string): boolean function isValidEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } Note: The regex above is basic — adjust according to project needs. Example 2: Quick API skeleton (Node.js/Express) // Create route GET /health that returns { status: 'ok' } app.get('/health', (req, res) => { res.json({ status: 'ok' }); }); Example 3: Basic unit test (Jest) // Write test for sum(a,b): 1+2=3, -1+1=0 test('sum basics', () => { expect(sum(1, 2)).toBe(3); expect(sum(-1, 1)).toBe(0); }); Tips for Using GitHub Copilot Effectively Write clear descriptions/comments: specify input, output, constraints, and examples.Always check & optimize code: run lint/tests, review performance, security.Break down complex requests: guide step by step for more accurate suggestions.Use Copilot Chat to research/explain, but always verify with original docs. Key Notes Enable “block suggestions matching public code” in organizational projects.Avoid pasting secrets (keys, credentials, sensitive data) into prompts. Conclusion GitHub Copilot is an AI assistant that helps you code faster, learn new tech quickly, and automate repetitive tasks — but you still need to review, test, and follow security policies. My Personal Experience Coding with GitHub Copilot Before using GitHub Copilot: Spent lots of time on repetitive, structured code.Slowed down by switching between coding and researching online. When first trying Copilot: Felt efficiency in simple features/functions.Struggled with complex features — Copilot often generated unnecessary code.Spent extra time reviewing Copilot’s output. After long-term use: Significantly reduced time on repetitive tasks (boilerplate, data mapping, simple CRUD, …).More consistent code (naming, structure), better documentation (docs, README) thanks to quick suggestions.Changed workflow: “comment-first” or “test-first” to guide Copilot, using Chat to refine and explain.Formed a risky habit: accepting Copilot’s suggestions too quickly without reviewing. Start Small & Measure Effectiveness Enable Copilot in your IDE, try with a utility function or basic test, turn on the “block public code” filter, and avoid pasting secrets. After one week, measure effectiveness (task completion time, amount of boilerplate written manually, number of minor bugs), then decide how much to apply in projects. Good luck using GitHub Copilot effectively — and may you achieve great success at the Hackathon!

                22/08/2025

                197

                Anh Nguyen T.

                Knowledge

                +0

                  How Could You Join a Hackathon Without Knowing This?

                  22/08/2025

                  197

                  Anh Nguyen T.

                  Customize software background

                  Want to customize a software for your business?

                  Meet with us! Schedule a meeting with us!