2 điểm bởi GN⁺ 2023-07-10 | 3 bình luận | Chia sẻ qua WhatsApp
  • Object Pascal hướng tới đồng thời một ngôn ngữ hướng đối tượng hiện đại, dễ đọchiệu năng native, là một lựa chọn để xây dựng ứng dụng dễ bảo trì trên nhiều nền tảng
  • Nhờ kiểu mạnh, kiểm tra lúc biên dịch và kiểm tra lúc chạy, các lỗi như gõ sai tên hoặc không khớp kiểu dễ được phát hiện trước khi đến tay người dùng
  • Khi cần, có thể dùng con trỏ, mã riêng cho từng OS/CPU, thậm chí assembly, nhưng Castle Game Engine chọn duy trì mã nhanh mà không cần assembly
  • Có thể nhắm tới phạm vi rất rộng: Windows, Linux, macOS, mobile, console, web; trong Castle Game Engine, mã engine và mã game được viết bằng cùng một ngôn ngữ
  • Với tích hợp FPC, Lazarus, Delphi, VS Code và khả năng liên kết với nhiều thư viện, cũng có thể xây dựng một luồng phát triển thực dụng trong hệ sinh thái Pascal

Object Pascal dễ đọc và an toàn kiểu

  • Object Pascal được xem là một ngôn ngữ đa nền tảng an toàn kiểu, hiện đại, dễ đọc và nhanh
  • Nếu đã biết các ngôn ngữ hướng đối tượng khác, bạn có thể học tương đối dễ dàng; có thể dùng Modern Object Pascal Introduction for Programmers làm tài liệu học
  • Có các tính năng được kỳ vọng ở một ngôn ngữ hướng đối tượng hiện đại
    • class
    • unit
    • property
    • generic
    • interface
    • reflection
    • closure
  • Cú pháp tập trung vào mã dễ đọc
  • Để đảm bảo an toàn kiểu, ngôn ngữ cung cấp các kiểu riêng như boolean, string, char, set, enum, range
    • Các chuyển đổi an toàn, chẳng hạn gán số nguyên cho float, được xử lý dễ dàng
    • Các chuyển đổi khác phải được thực hiện một cách tường minh

Cách bắt lỗi ở giai đoạn biên dịch và lúc chạy

  • Object Pascal nhấn mạnh kiểm tra lúc biên dịch
  • Khi refactor, chẳng hạn sắp xếp lại cấu trúc dữ liệu, có thể khiến compiler chỉ ra những vị trí cần chỉnh sửa
  • Những lỗi rõ ràng như gõ sai tên hoặc không khớp kiểu sẽ không vượt qua được bước biên dịch, nên không đến tay người dùng
  • Ngôn ngữ cũng cung cấp thêm các kiểm tra lúc chạy
    • kiểm tra phạm vi mảng
    • kiểm tra tràn số nguyên
    • assertion
    • kiểm tra rò rỉ bộ nhớ
  • Kiểm tra lúc chạy được dùng để phát hiện vấn đề trong bản debug, và có thể tắt trong bản release khi hiệu năng là quan trọng
  • Khi biên dịch bằng CGE editor, chế độ debug / release được thiết lập tự động, và có thể chuyển chế độ trong menu “Run”
  • Có thể tham khảo các tài liệu liên quan: What are range and overflow checks (and errors) in PascalDetecting Memory Leaks

Hiệu năng native và khả năng kiểm soát cấp thấp khi cần

  • Object Pascal được biên dịch thành native code, nên dễ có được hiệu năng thực thi cơ bản tốt
  • Với các ứng dụng thông thường, không có nhiều trường hợp cần đi xuống tối ưu hóa cấp thấp
  • Khi cần, có thể dùng các tính năng cấp thấp ở mức mong muốn
    • sử dụng con trỏ
    • phép toán con trỏ
    • viết mã riêng cho từng OS/CPU
    • thêm mã assembly
  • Để tăng tính di động và khả năng đọc mã, Castle Game Engine hướng tới thực thi nhanh dù hoàn toàn không có mã assembly
  • Tốc độ biên dịch cũng khá nhanh; có trường hợp khi mở một dự án mới lần đầu, bản build desktop mất 2,5 giây và bản build Android mất 10,1 giây

Nhiều nền tảng và cách phát triển của Castle Game Engine

  • Object Pascal có thể dùng để nhắm tới nhiều nền tảng khác nhau
    • Desktop: Windows, Linux, macOS, Raspberry Pi, FreeBSD, có lẽ là mọi Unix
    • Mobile: Android, iOS
    • Console: Nintendo Switch
    • Web: WebAssembly, JS dùng pas2js
  • Có thể xem các nền tảng mà Castle Game Engine hỗ trợ tại Castle Game Engine platforms supported
  • Để biết toàn bộ các mục tiêu có thể có, tham khảo FPC target platformsDelphi target platforms
  • Trong Castle Game Engine, mã engine và mã game được viết bằng cùng một ngôn ngữ
  • Engine là mã nguồn mở, và có thể fork, chỉnh sửa CGE theo nhu cầu

Hệ sinh thái thư viện và công cụ phát triển

  • Pascal có nhiều thư viện và unit sẵn có trong nhiều lĩnh vực
    • cơ sở dữ liệu
    • XML, JSON
    • AI
    • blockchain
    • networking
  • Có thể dễ dàng tích hợp hoặc liên kết với các thư viện hiện có có C API
    • renderer
    • thư viện âm thanh
    • engine vật lý
  • Cũng có thể dùng Python libraries in Pascal
  • Hệ sinh thái công cụ chính như sau
    • FPC: Free Pascal Compiler mã nguồn mở
    • Lazarus: IDE Pascal mã nguồn mở dựa trên FPC
    • Delphi: compiler và IDE Pascal thương mại
    • VS Code: CGE và nhiều công cụ trong hệ sinh thái Pascal hỗ trợ rõ ràng tích hợp với VS Code

3 bình luận

 
gmong 2023-07-20

Delphi... thật gợi nhớ. Borland, Delmadang..

 
xguru 2023-07-10

Vào thời còn phát triển Windows, có lẽ Object Pascal với Delphi thực sự là số một.

 
GN⁺ 2023-07-10
Ý kiến trên Hacker News
  • Nếu từng dùng Delphi trước đây, rất có khả năng bạn đã biết Lazarus. Lazarus thực chất gần như là một bản tái triển khai mã nguồn mở, và có thể chạy/biên dịch native gần như ở mọi nơi, kể cả các bo mạch ARM như Raspberry Pi
    Tuy nhiên việc cài đặt thư viện có thể hơi phiền phức, nên FpcUp, rồi sau đó là FpcUpDeluxe, được tạo ra để tự động hóa việc cài đặt IDE, các module và một số add-on khá thú vị
    https://wiki.freepascal.org/fpcupdeluxe
    Cũng có một demo widget bảng điều khiển được làm vội bằng các widget miễn phí đi kèm FpcUpDeluxe
    https://ibb.co/9bchx7T
    FpcUpDeluxe cũng chạy trên Alpine Linux; chỉ cần tải bản musl từ trang phát hành. Vì vậy, nó mở ra khả năng đưa bảng điều khiển vào cả những hệ thống rất nhỏ. Trên nhiều nền tảng, mã được biên dịch native và chạy nhanh, không cần trình thông dịch hay trình duyệt web

  • Có thời tôi dùng Delphi/Pascal làm ngôn ngữ chính, và trong 10–20 năm qua đã đi tìm một ngôn ngữ phù hợp với mình. Tôi cũng dùng Haxe khá lâu, nhưng cuối cùng có cảm giác rơi vào cái bẫy “cứ làm bằng macro là được”. Macro có thể làm mọi thứ, nhưng khi có đủ nhiều macro, ai cũng sẽ lập trình bằng ngôn ngữ mở rộng macro của riêng mình
    JavaScript đã có những cải tiến ổn và vẫn còn cần thêm, nhưng hiện tôi cũng làm khá nhiều việc bên đó. Vài năm trước, khi viết mã cho AVR 8-bit, tôi thử dùng lại FreePascal và thấy thật sự rất thú vị. Dùng các tính năng mới, tôi cảm thấy nó đúng là một ngôn ngữ hiện đại; tôi cũng thích việc khi nhắm tới không gian nhỏ, mình gần như không dùng thư viện chuẩn mà tự viết những đoạn mã cần thiết
    Nhờ vậy tôi tránh được lớp nhiễu namespace do FreePascal tích lũy qua nhiều năm để giữ tương thích ngược, chẳng hạn các tầng như TList, TFPList, TFPGList, TFPGObjectList. Điều đáng tiếc nhất là trên các mục tiêu không có FPU hoặc mô phỏng FPU, trình biên dịch không cho phép biểu thức số thực hằng. Vì có thể tính ở thời điểm biên dịch, giá mà nó được hỗ trợ thì tốt
    Sau khi dùng các môi trường khác, việc không thể định nghĩa biến ở giữa hàm giờ đây khiến tôi thấy như một hạn chế, và tôi cũng muốn có phạm vi ở mức thấp hơn hàm. Khác biệt giữa begin/end và {} thì tôi không bận tâm lắm. Hiện tôi thích các ngôn ngữ phân biệt chữ hoa chữ thường hơn, và cho rằng không nên gắn tiền tố chữ cái vào kiểu. Có lẽ trên hết là nhờ sự tiến bộ của trình soạn thảo. Tô màu cú pháp và lint thời gian thực đã chuyển thông tin sang vùng riêng, giảm nhiễu trong văn bản
    Nếu một ngôn ngữ kế thừa FreePascal xuất hiện theo kiểu khởi đầu mới, tôi nghĩ mình sẽ khá hào hứng. Tôi muốn có một thư viện chuẩn mới coi các tính năng hiện đại là công dân hạng nhất, và biết đâu khi nghỉ hưu tôi sẽ thử làm một cái

    • begin/end và {} thực ra không có cùng ý nghĩa. {} định nghĩa phạm vi cục bộ, còn begin/end thì không
  • Tôi từng dùng Delphi trong công việc vài năm vào thập niên 90 và rất thích nó, nhưng đã mệt mỏi vì Borland và các chủ sở hữu sau đó liên tục quản lý sai sản phẩm và ngôn ngữ. Anders Hejlsberg cũng rời Borland sang Microsoft và tạo ra C#, cá nhân tôi cho rằng đó là một ngôn ngữ và kiến trúc đáng đầu tư thời gian hơn nhiều

    • Việc triển khai ứng dụng desktop C# một cách ổn định gần như là ác mộng hoàn toàn so với một file exe duy nhất mà Delphi/Lazarus tạo ra
  • Dạo này tôi dùng Pascal cho vui vì các ràng buộc về tài nguyên. Turbo Pascal 3.00A của Borland ngày xưa chạy trên CP/M, cung cấp cả trình soạn thảo, trình biên dịch và thư viện trong phạm vi 64KB
    Nó đủ nhanh để dùng theo kiểu tương tác, và tạo ra mã đủ tốt để triển khai các tiện ích cấp thấp, game đơn giản hay đủ thứ hack linh tinh. Tôi chưa từng dùng Pascal trong môi trường lớn hơn hoặc hiện đại hơn, nhưng trải nghiệm gần đây khá hài lòng nên không định loại nó ra

    • Turbo Pascal và sau này là Delphi là khoảnh khắc đầu tiên khiến một ngôn ngữ lập trình thật sự “chạm” tới tôi. Cuối cùng tôi đi theo C và C++, nhưng tôi luôn muốn quay lại một ngôn ngữ có sức biểu đạt hơn
      Tôi không biết là vẫn còn các hiện thực Pascal hiện đại, có lẽ nên làm thân lại với mối tình đầu
    • Nếu chưa thử, bạn nên xem qua Free Pascal. Nó hỗ trợ nhiều nền tảng
      Nếu cần CP/M thì có thể kiểm tra trên trang web xem có hỗ trợ không, và tôi cũng sẽ không ngạc nhiên nếu có. IDE giao diện văn bản rất giống Turbo Pascal và nhanh như chớp. Ngôn ngữ có nhiều tính năng cao cấp hơn Turbo Pascal rất nhiều, nhưng nếu không muốn thì bạn không cần dùng
      Trước đây khi tôi thử nhanh trên Windows, binary tạo ra cũng rất nhỏ như C, một chương trình hello world đơn giản dưới 50–60KB
    • Ôi, nỗi hoài niệm Pascal. Thời TRS-80 Model III, tôi đã dành dụm một khoản lớn 80–100 đô la để mua gói Pascal 80, phiên bản New Classics. Về cơ bản đó là một IDE sơ khai và khá tuyệt theo tiêu chuẩn thời đó. http://www.trs-80.org/pascal-80/
      Tôi nhớ nó là một bước tiến khổng lồ so với môi trường phát triển M-III BASIC, và game cùng tiện ích tôi viết chạy khá tốt ngay trong 48KB RAM. Tôi tò mò không biết codebase Pascal-80 đã ra sao. Chắc chắn nó không thể tốt hơn các công cụ hiện đại cho phần cứng retro, và có lẽ còn kém xa. “Oh Pascal!” là cuốn sách tôi dùng để học ngôn ngữ này, và vì đó là vài năm trước khi Pascal được dùng thương mại, chắc hẳn không có nhiều lựa chọn khác
  • Tôi khó đồng ý với vài lý do. Object Pascal không phải là một ngôn ngữ hiện đại. Năm 1998 thì có thể là vậy, nhưng sau đó nó không phát triển nhiều, và thay đổi lớn gần nhất cũng là generics, thứ được đưa vào muộn hơn gần như mọi ngôn ngữ khác
    FPC cũng không tạo ra mã đặc biệt nhanh, và đặc tính đối tượng của Object Pascal cũng không có lợi cho tính cục bộ. Nó nhanh hơn ngôn ngữ script, nhưng nhìn chung chậm hơn các ngôn ngữ biên dịch trước thông thường, kể cả những ngôn ngữ có garbage collection
    Mặt khác, hệ sinh thái thì tuyệt vời. Có nhiều thư viện và công cụ tốt, đáng chú ý nhất là Lazarus, một bản clone của Delphi. Những người dùng FPC hay Delphi dường như không mấy quan tâm đến chuyện hiện đại hóa ngôn ngữ, mà chỉ đơn giản là hoàn thành công việc. Tuy vậy, tôi không nghĩ nó hấp dẫn với lập trình viên mới, nên không rõ tương lai sẽ ra sao

    • Generics được đưa vào FPC đã 17 năm trước, nên còn lâu mới là thay đổi gần đây. Nếu nói về thay đổi lớn được thêm gần đây, tôi nghĩ các ứng viên phù hợp hơn là hàm ẩn danh và tham chiếu hàm, tức closure
      Hiệu năng thực tế là đủ tốt, và khi tìm thấy nút thắt cổ chai thì cũng có thể tối ưu đến mức cần thiết. So với C++, dùng các class “cấp cao” có thể phiền hơn một chút, nhưng không phải là không thể
      Nếu muốn hiệu năng mặc định với nỗ lực tối thiểu thì cũng có backend LLVM mới. Vì phải build cả runtime library, FCL, v.v. bằng backend LLVM nên cần build trình biên dịch từ source, nhưng chỉ mất vài phút. Đổi lại trình biên dịch chậm hơn rất nhiều, và cá nhân tôi không thấy chênh lệch hiệu năng đáng để đánh đổi
    • Có vẻ bạn đánh giá nó quá thấp. Trước đây nó từng được benchmark nhanh ngang C++, và trong mục đích chính là ứng dụng GUI cục bộ, tôi chưa thấy thứ gì phản hồi tức thì như vậy, kể cả các ứng dụng GUI C#
      Vì thế tôi tò mò benchmark nào đã kết luận nó chậm hơn thực tế khoảng 50 lần
    • Tôi không rõ FPC, nhưng Delphi 7 trong lập trình thi đấu 10 năm trước ở mức tương đương C++ và nhanh hơn Java khoảng 2–3 lần
      Ở đây lập trình thi đấu nghĩa là các phép tính thuật toán đơn luồng, thiên về CPU, thời gian chạy ngắn tối đa 1–3 giây mỗi lần chạy; bất lợi cho JIT; dùng compiler và thiết lập runtime mặc định, không thư viện ngoài hay tinh chỉnh. Nhận thức phổ biến khi đó là dùng C++/Pascal, hoặc làm bằng Java rồi nếu bị “time limit exceeded” thì viết lại lời giải 200–300 dòng sang C++ để được chấp nhận
    • Khác biệt lớn nhất giữa Pascal và C++ là trải nghiệm lập trình viên
      Pascal dùng compiler LL(1) một pass nên có thể biên dịch ở mức mili giây. Nó mang lại trải nghiệm như REPL, nơi Edit→Compile→Run hoàn tất trong chưa tới 1 giây. C/C++ với macro và thời gian biên dịch chậm có trải nghiệm lập trình viên tệ hơn, và ít nhất đó là lý do tôi học Pascal thay vì C, Delphi thay vì C++
    • Tôi không đồng ý mạnh với nhận định hệ sinh thái tuyệt vời. Tôi đã làm việc với Pascal khoảng 10 năm, và thường xuyên bực bội vì thiếu các thư viện hiện đại, cuối cùng phải tự tạo giải pháp hoặc từ bỏ toàn bộ ý tưởng
  • Không hiểu vì sao nhất thiết phải làm vậy. Ngôn ngữ cũ cần tồn tại để hỗ trợ legacy, nhưng tôi không thấy nhiều ý nghĩa trong việc cố nhét những tính năng hiện đại đó vào các ngôn ngữ cũ
    Tôi dùng Java khá nhiều, nhưng nói thật tôi nghĩ gần như mọi tính năng sau Java 8 lẽ ra không nên được thêm vào. Ví dụ, lambda trong Java gần như chỉ là vá víu
    Nếu muốn tính năng hiện đại thì cứ dùng ngôn ngữ hiện đại. Nếu muốn ở lại trong hệ sinh thái Java thì dùng Kotlin là được. Pascal thì đúng nghĩa là tôi đã không thấy suốt mấy chục năm, và lần cuối tôi lập trình bằng nó là vào thập niên 1980 nên tôi chỉ nói chuyện Java, nhưng việc thêm một danh sách tính năng như vậy vào Pascal trông khá buồn cười

    • Lambda là vá víu ư? Thật sự bạn cho rằng tạo một lớp ẩn danh chỉ có một phương thức là tốt hơn sao?
    • Trong Java, khả năng tương tác giữa các ngôn ngữ dễ nên các lựa chọn như Kotlin cũng dễ hơn. Clojure cũng vậy. Nhưng nếu đang dùng C++ thì không có con đường dễ dàng để nâng cấp sang thứ khác
      Dù vậy, việc nhét thêm các tính năng hiện đại vẫn có giá trị. Bạn có thể không bắt đầu dự án mới bằng C++ mà chọn một ngôn ngữ hiện đại như Rust, nhưng hàng triệu dòng mã C++ đã viết sẵn có thể được cải thiện bằng các tính năng hiện đại. Chỉ cần nhìn cách C++11 thay đổi cuộc chơi là thấy
    • Vậy thì sẽ phải thay đổi ngôn ngữ lập trình thường xuyên hơn nhiều. Để làm chậm quá trình này, việc thêm và tích hợp các tính năng mới đã được chứng minh là có lợi có vẻ hợp lý
    • Cho đến gần đây, ngoài hệ sinh thái khổng lồ đến vô lý, Java có ít điểm hơn Delphi 15 năm trước. Tất nhiên hệ sinh thái đó thắng tất cả
      Ngôn ngữ Java, vì quyết định dùng thư viện thay cho tính năng ngôn ngữ, đã tạo ra một lượng mã khuôn mẫu khổng lồ, và tôi cho rằng hướng đi đó là sai. Những gì làm được trong Python, Lisp, Haskell thì cũng đều làm được trong Java, nhưng theo định nghĩa thì trong brainf*ck cũng làm được. Độ phức tạp của giải pháp Java thực tế cao hơn các ngôn ngữ giàu tính năng, và rốt cuộc hoặc là tái triển khai các tính năng ngôn ngữ đó theo cách hơi hỏng, hoặc kéo vào cả đống dependency để thay thế. Dù cách nào thì bề mặt API cần học cũng chỉ tăng thêm
    • Các ngôn ngữ JVM có tính cạnh tranh mới chỉ xuất hiện trong vài năm gần đây. Scala là một ngõ cụt, Clojure gần như là một trào lưu, còn Rhino/JS có tham vọng rất hạn chế
      Nhờ các cải tiến của Java mà JVM tiếp tục giữ được tính liên quan và chặn được DotNet; xét đến lịch sử của Microsoft thì đó là điều tốt
  • Thường bị bỏ qua, nhưng hệ sinh thái nhúng Ada có lợi thế về mức độ trưởng thành của phân tích tĩnh, gỡ lỗi và hỗ trợ mục tiêu

    • Tôi luôn nghĩ Ada bị đánh giá thấp. Cá nhân tôi đánh giá cao các tính năng như an toàn bộ nhớ, mô hình đồng thời chuẩn, hỗ trợ kiểu đơn vị/đo lường, biên dịch trước
      Cú pháp giống Pascal của Ada trông dài dòng nhưng không khó đọc. VHDL cũng dựa trên cú pháp Ada nên có thể dễ hơn với những người dùng cả hai ngôn ngữ
      Swift cũng đáp ứng một phần trong số này, và còn thêm các tính năng tiện như closure, đếm tham chiếu tự động, suy luận kiểu. Tôi không rõ về kiểu đo lường, nhưng có vẻ có thể triển khai được. Tuy nhiên hiện vẫn chưa có HDL nào giống Swift
    • Tôi thắc mắc liệu Ada giờ đã hỗ trợ đích Android và iOS chưa. Lần cuối tôi xem thì dường như không có cách rõ ràng để build cho NDK
    • Trên macOS thì nó không phải là lựa chọn thân thiện nhất để bắt đầu
  • Pascal thực sự tốt và hiệu năng cũng ổn. Đó là ngôn ngữ thứ hai tôi học sau Basic hồi trung học
    Tôi không hiểu vì sao ngành này phải thụt lùi sang Python, Ruby, Java, JavaScript vào cuối thập niên 90 và đầu những năm 2000

    • Gần đây tôi đã xem một bài thuyết trình về chủ đề này: https://www.youtube.com/watch?v=Tml94je2edk
      Nó giải thích lý do các ngôn ngữ kiểu động như Python, Ruby, JS trở nên phổ biến trong thập niên 90: vì khi làm website, chúng cung cấp vòng phản hồi nhanh và không cần IDE hay trình biên dịch. Thời đó IDE và trình biên dịch chậm, và nhiều khi không miễn phí
      Dù sao thì người dùng khi ấy còn truy cập bằng modem 56k, nên đánh đổi thời gian phát triển để lấy cải thiện hiệu năng cũng không có lợi mấy. Bài thuyết trình còn có nhiều điểm thú vị về cách phương thức phát triển đã thay đổi trong 10–20 năm qua, và vì sao xu hướng lại đang chuyển về kiểu tĩnh
    • Máy tính đã nhanh hơn và bộ nhớ cũng nhiều hơn, nên phải tạo ra chỗ để dùng chúng thôi ;-)
      Ngoài ra, trình duyệt web đã trở thành một nền tảng lập trình phổ biến và chủ yếu dùng JavaScript. Ngay cả bây giờ, ngoài phần trình duyệt, người ta còn đang cố nhét một hệ điều hành hoàn chỉnh vào bên trong trình duyệt web, và Chrome thì đang tiến khá gần tới điều đó
  • Năm nhất đại học, dự án đầu tiên của tôi là một trình mô phỏng thang máy viết bằng Pascal, dùng đồ họa văn bản. So với các ngôn ngữ họ C, Pascal có một thứ gì đó thanh nhã nên rất thú vị
    Vì vậy dạo này tôi thích Nim; theo tôi biết, Nim chịu ảnh hưởng từ các ngôn ngữ họ Wirth như Pascal, Modula-3, Oberon, Delphi, cũng như Ada và Python

  • Pascal không tệ lắm, và thực ra tôi nghĩ nó còn có ưu điểm so với một số ngôn ngữ lập trình hiện đại. Tất nhiên nó không hoàn hảo và cũng có nhược điểm
    Thỉnh thoảng tôi dùng Pascal và BASIC cho lập trình DOS, và ít nhất với mục đích đó thì Pascal có vẻ ổn. C cũng được dùng cho lập trình DOS, nhưng đặc biệt trong real mode thì trông không hay lắm
    Với lập trình Linux, nhìn chung tôi thích C hơn nhưng cũng dùng PostScript. Tôi nghĩ cả C lẫn PostScript đều có ưu điểm so với một số ngôn ngữ hiện đại. Pascal cũng có thể dùng cho các chương trình khác, thậm chí TeX cũng được viết bằng Pascal

    • Tôi tò mò bạn dùng PostScript vào việc gì. Thấy những người dùng nó cho mục đích khác ngoài công việc liên quan đến in ấn thì khá thú vị